puma 6.2.2 → 6.3.1
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 +38 -2
- data/LICENSE +0 -0
- data/README.md +24 -0
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +0 -0
- data/docs/compile_options.md +0 -0
- data/docs/deployment.md +0 -0
- data/docs/fork_worker.md +0 -0
- 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 +0 -0
- data/docs/testing_test_rackup_ci_files.md +0 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +0 -0
- data/ext/puma_http11/http11_parser.c +0 -0
- data/ext/puma_http11/http11_parser.h +0 -0
- data/ext/puma_http11/http11_parser.java.rl +0 -0
- data/ext/puma_http11/http11_parser.rl +0 -0
- data/ext/puma_http11/http11_parser_common.rl +0 -0
- data/ext/puma_http11/mini_ssl.c +30 -2
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +0 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -0
- data/ext/puma_http11/puma_http11.c +0 -0
- data/lib/puma/app/status.rb +1 -1
- data/lib/puma/binder.rb +8 -6
- data/lib/puma/cli.rb +0 -0
- data/lib/puma/client.rb +18 -10
- data/lib/puma/cluster/worker.rb +0 -0
- data/lib/puma/cluster/worker_handle.rb +0 -0
- data/lib/puma/cluster.rb +0 -0
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +0 -0
- data/lib/puma/const.rb +58 -9
- data/lib/puma/control_cli.rb +0 -0
- data/lib/puma/detect.rb +0 -0
- data/lib/puma/dsl.rb +34 -1
- data/lib/puma/error_logger.rb +0 -0
- data/lib/puma/events.rb +0 -0
- data/lib/puma/io_buffer.rb +0 -0
- data/lib/puma/jruby_restart.rb +0 -0
- data/lib/puma/json_serialization.rb +0 -0
- data/lib/puma/launcher/bundle_pruner.rb +0 -0
- data/lib/puma/launcher.rb +0 -0
- data/lib/puma/log_writer.rb +1 -1
- data/lib/puma/minissl/context_builder.rb +1 -0
- data/lib/puma/minissl.rb +17 -0
- data/lib/puma/plugin/systemd.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +2 -2
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +16 -7
- data/lib/puma/request.rb +12 -6
- data/lib/puma/runner.rb +0 -0
- data/lib/puma/sd_notify.rb +0 -0
- data/lib/puma/server.rb +16 -4
- data/lib/puma/single.rb +0 -0
- data/lib/puma/state_file.rb +0 -0
- data/lib/puma/thread_pool.rb +7 -3
- data/lib/puma/util.rb +0 -0
- data/lib/puma.rb +0 -0
- data/lib/rack/handler/puma.rb +6 -2
- data/tools/Dockerfile +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcbde9283993550beb848a4f777bf9d33a1e163f5356cfeeb40be3eede72e7d0
|
4
|
+
data.tar.gz: 5394fdd8307e5a1fd40c7cf560d01565a6a9d69fd0fa0006ff6b28e483e627aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 473b3047986b69763e01fb3b3f7fc1137070cb041ae235e520216e568860295a3b0ed105e4c52ee1d3aa05353d1b247e0782a1aa7bde840a540200f21d84320b
|
7
|
+
data.tar.gz: 69e625526fcc0b7216a419326e172114ed0ba4c7842722c1f896ed4d2fd559e4b58ea31f95a7ca52d37f11b5930433cfa6faab3f510996a39b1de3d3ff46d2a7
|
data/History.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## 6.3.1 / 2023-08-18
|
2
|
+
|
3
|
+
* Security
|
4
|
+
* Address HTTP request smuggling vulnerabilities with zero-length Content Length header and trailer fields ([GHSA-68xg-gqqm-vgj8](https://github.com/puma/puma/security/advisories/GHSA-68xg-gqqm-vgj8))
|
5
|
+
|
6
|
+
## 6.3.0 / 2023-05-31
|
7
|
+
|
8
|
+
* Features
|
9
|
+
* Add dsl method `supported_http_methods` ([#3106], [#3014])
|
10
|
+
* Puma error responses no longer have any fingerprints to indicate Puma ([#3161], [#3037])
|
11
|
+
* Support decryption of SSL key ([#3133], [#3132])
|
12
|
+
|
13
|
+
* Bugfixes
|
14
|
+
* Don't send 103 early hints response when only invalid headers are used ([#3163])
|
15
|
+
* Handle malformed request path ([#3155], [#3148])
|
16
|
+
* Misc lib file fixes - trapping additional errors, CI helper ([#3129])
|
17
|
+
* Fixup req form data file upload with "r\n" line endings ([#3137])
|
18
|
+
* Restore rack 1.6 compatibility Restore rack 1.6 compatibility ([#3156])
|
19
|
+
|
20
|
+
* Refactor
|
21
|
+
* const.rb - Update Puma::HTTP_STATUS_CODES ([#3162])
|
22
|
+
* Clarify Reactor#initialize ([#3151])
|
23
|
+
|
1
24
|
## 6.2.2 / 2023-04-17
|
2
25
|
|
3
26
|
* Bugfixes
|
@@ -22,7 +45,6 @@
|
|
22
45
|
* commonlogger.rb - fix HIJACK time format, use constants, not strings ([#3074])
|
23
46
|
* Fixed some edge cases regarding request hijacking ([#3072])
|
24
47
|
|
25
|
-
|
26
48
|
## 6.1.1 / 2023-02-28
|
27
49
|
|
28
50
|
* Bugfixes
|
@@ -1979,6 +2001,20 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1979
2001
|
* Bugfixes
|
1980
2002
|
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
|
1981
2003
|
|
2004
|
+
[#3106]:https://github.com/puma/puma/pull/3106 "PR by @MSP-Greg, merged 2023-05-29"
|
2005
|
+
[#3014]:https://github.com/puma/puma/issues/3014 "Issue by @kyledrake, closed 2023-05-29"
|
2006
|
+
[#3161]:https://github.com/puma/puma/pull/3161 "PR by @MSP-Greg, merged 2023-05-27"
|
2007
|
+
[#3037]:https://github.com/puma/puma/issues/3037 "Issue by @daisy1754, closed 2023-05-27"
|
2008
|
+
[#3133]:https://github.com/puma/puma/pull/3133 "PR by @stanhu, merged 2023-04-30"
|
2009
|
+
[#3132]:https://github.com/puma/puma/issues/3132 "Issue by @stanhu, closed 2023-04-30"
|
2010
|
+
[#3163]:https://github.com/puma/puma/pull/3163 "PR by @MSP-Greg, merged 2023-05-27"
|
2011
|
+
[#3155]:https://github.com/puma/puma/pull/3155 "PR by @dentarg, merged 2023-05-14"
|
2012
|
+
[#3148]:https://github.com/puma/puma/issues/3148 "Issue by @dentarg, closed 2023-05-14"
|
2013
|
+
[#3129]:https://github.com/puma/puma/pull/3129 "PR by @MSP-Greg, merged 2023-05-02"
|
2014
|
+
[#3137]:https://github.com/puma/puma/pull/3137 "PR by @MSP-Greg, merged 2023-04-30"
|
2015
|
+
[#3156]:https://github.com/puma/puma/pull/3156 "PR by @severin, merged 2023-05-16"
|
2016
|
+
[#3162]:https://github.com/puma/puma/pull/3162 "PR by @MSP-Greg, merged 2023-05-23"
|
2017
|
+
[#3151]:https://github.com/puma/puma/pull/3151 "PR by @nateberkopec, merged 2023-05-12"
|
1982
2018
|
[#3118]:https://github.com/puma/puma/pull/3118 "PR by @ninoseki, merged 2023-04-01"
|
1983
2019
|
[#3117]:https://github.com/puma/puma/issues/3117 "Issue by @ninoseki, closed 2023-04-01"
|
1984
2020
|
[#3109]:https://github.com/puma/puma/pull/3109 "PR by @ahorek, merged 2023-03-31"
|
@@ -2089,7 +2125,7 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
2089
2125
|
[#2794]:https://github.com/puma/puma/pull/2794 "PR by @johnnyshields, merged 2022-01-10"
|
2090
2126
|
[#2759]:https://github.com/puma/puma/pull/2759 "PR by @ob-stripe, merged 2021-12-11"
|
2091
2127
|
[#2731]:https://github.com/puma/puma/pull/2731 "PR by @baelter, merged 2021-11-02"
|
2092
|
-
[#2341]:https://github.com/puma/puma/issues/2341 "Issue by @cjlarose,
|
2128
|
+
[#2341]:https://github.com/puma/puma/issues/2341 "Issue by @cjlarose, opened 2020-08-18"
|
2093
2129
|
[#2728]:https://github.com/puma/puma/pull/2728 "PR by @dalibor, merged 2021-10-31"
|
2094
2130
|
[#2733]:https://github.com/puma/puma/pull/2733 "PR by @ob-stripe, merged 2021-12-12"
|
2095
2131
|
[#2807]:https://github.com/puma/puma/pull/2807 "PR by @MSP-Greg, merged 2022-01-25"
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -279,6 +279,30 @@ $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_f
|
|
279
279
|
List of available flags: `USE_CHECK_TIME`, `CRL_CHECK`, `CRL_CHECK_ALL`, `IGNORE_CRITICAL`, `X509_STRICT`, `ALLOW_PROXY_CERTS`, `POLICY_CHECK`, `EXPLICIT_POLICY`, `INHIBIT_ANY`, `INHIBIT_MAP`, `NOTIFY_POLICY`, `EXTENDED_CRL_SUPPORT`, `USE_DELTAS`, `CHECK_SS_SIGNATURE`, `TRUSTED_FIRST`, `SUITEB_128_LOS_ONLY`, `SUITEB_192_LOS`, `SUITEB_128_LOS`, `PARTIAL_CHAIN`, `NO_ALT_CHAINS`, `NO_CHECK_TIME`
|
280
280
|
(see https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_hostflags.html#VERIFICATION-FLAGS).
|
281
281
|
|
282
|
+
#### Controlling OpenSSL Password Decryption
|
283
|
+
|
284
|
+
To enable runtime decryption of an encrypted SSL key (not available for JRuby), use `key_password_command`:
|
285
|
+
|
286
|
+
```
|
287
|
+
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&key_password_command=/path/to/command.sh'
|
288
|
+
```
|
289
|
+
|
290
|
+
`key_password_command` must:
|
291
|
+
|
292
|
+
1. Be executable by Puma.
|
293
|
+
2. Print the decryption password to stdout.
|
294
|
+
|
295
|
+
For example:
|
296
|
+
|
297
|
+
```shell
|
298
|
+
#!/bin/sh
|
299
|
+
|
300
|
+
echo "this is my password"
|
301
|
+
```
|
302
|
+
|
303
|
+
`key_password_command` can be used with `key` or `key_pem`. If the key
|
304
|
+
is not encrypted, the executable will not be called.
|
305
|
+
|
282
306
|
### Control/Status Server
|
283
307
|
|
284
308
|
Puma has a built-in status and control app that can be used to query and control Puma.
|
data/bin/puma-wild
CHANGED
File without changes
|
data/docs/architecture.md
CHANGED
File without changes
|
data/docs/compile_options.md
CHANGED
File without changes
|
data/docs/deployment.md
CHANGED
File without changes
|
data/docs/fork_worker.md
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/docs/jungle/README.md
CHANGED
File without changes
|
data/docs/jungle/rc.d/README.md
CHANGED
File without changes
|
data/docs/jungle/rc.d/puma.conf
CHANGED
File without changes
|
data/docs/kubernetes.md
CHANGED
File without changes
|
data/docs/nginx.md
CHANGED
File without changes
|
data/docs/plugins.md
CHANGED
File without changes
|
data/docs/rails_dev_mode.md
CHANGED
File without changes
|
data/docs/restart.md
CHANGED
File without changes
|
data/docs/signals.md
CHANGED
File without changes
|
data/docs/stats.md
CHANGED
File without changes
|
data/docs/systemd.md
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/ext/puma_http11/ext_help.h
CHANGED
File without changes
|
data/ext/puma_http11/extconf.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -185,6 +185,18 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
|
185
185
|
return preverify_ok;
|
186
186
|
}
|
187
187
|
|
188
|
+
static int password_callback(char *buf, int size, int rwflag, void *userdata) {
|
189
|
+
const char *password = (const char *) userdata;
|
190
|
+
size_t len = strlen(password);
|
191
|
+
|
192
|
+
if (len > (size_t) size) {
|
193
|
+
return 0;
|
194
|
+
}
|
195
|
+
|
196
|
+
memcpy(buf, password, len);
|
197
|
+
return (int) len;
|
198
|
+
}
|
199
|
+
|
188
200
|
static VALUE
|
189
201
|
sslctx_alloc(VALUE klass) {
|
190
202
|
SSL_CTX *ctx;
|
@@ -212,10 +224,12 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
212
224
|
SSL_CTX* ctx;
|
213
225
|
int ssl_options;
|
214
226
|
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
215
|
-
verification_flags, session_id_bytes, cert_pem, key_pem;
|
227
|
+
verification_flags, session_id_bytes, cert_pem, key_pem, key_password_command, key_password;
|
216
228
|
BIO *bio;
|
217
229
|
X509 *x509;
|
218
230
|
EVP_PKEY *pkey;
|
231
|
+
pem_password_cb *password_cb = NULL;
|
232
|
+
const char *password = NULL;
|
219
233
|
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
220
234
|
int min;
|
221
235
|
#endif
|
@@ -235,6 +249,8 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
235
249
|
|
236
250
|
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
237
251
|
|
252
|
+
key_password_command = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password_command"), 0);
|
253
|
+
|
238
254
|
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
239
255
|
|
240
256
|
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
@@ -261,6 +277,18 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
261
277
|
}
|
262
278
|
}
|
263
279
|
|
280
|
+
if (!NIL_P(key_password_command)) {
|
281
|
+
key_password = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password"), 0);
|
282
|
+
|
283
|
+
if (!NIL_P(key_password)) {
|
284
|
+
StringValue(key_password);
|
285
|
+
password_cb = password_callback;
|
286
|
+
password = RSTRING_PTR(key_password);
|
287
|
+
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
|
288
|
+
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) password);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
264
292
|
if (!NIL_P(key)) {
|
265
293
|
StringValue(key);
|
266
294
|
|
@@ -285,7 +313,7 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
285
313
|
if (!NIL_P(key_pem)) {
|
286
314
|
bio = BIO_new(BIO_s_mem());
|
287
315
|
BIO_puts(bio, RSTRING_PTR(key_pem));
|
288
|
-
pkey = PEM_read_bio_PrivateKey(bio, NULL,
|
316
|
+
pkey = PEM_read_bio_PrivateKey(bio, NULL, password_cb, (void *) password);
|
289
317
|
|
290
318
|
if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
|
291
319
|
BIO_free(bio);
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/puma/app/status.rb
CHANGED
@@ -80,7 +80,7 @@ module Puma
|
|
80
80
|
|
81
81
|
def authenticate(env)
|
82
82
|
return true unless @auth_token
|
83
|
-
env['QUERY_STRING'].to_s.split(
|
83
|
+
env['QUERY_STRING'].to_s.split('&;').include? "token=#{@auth_token}"
|
84
84
|
end
|
85
85
|
|
86
86
|
def rack_response(status, body, content_type='application/json')
|
data/lib/puma/binder.rb
CHANGED
@@ -48,7 +48,6 @@ module Puma
|
|
48
48
|
|
49
49
|
@envs = {}
|
50
50
|
@ios = []
|
51
|
-
localhost_authority
|
52
51
|
end
|
53
52
|
|
54
53
|
attr_reader :ios
|
@@ -451,11 +450,14 @@ module Puma
|
|
451
450
|
|
452
451
|
def close_listeners
|
453
452
|
@listeners.each do |l, io|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
453
|
+
begin
|
454
|
+
io.close unless io.closed?
|
455
|
+
uri = URI.parse l
|
456
|
+
next unless uri.scheme == 'unix'
|
457
|
+
unix_path = "#{uri.host}#{uri.path}"
|
458
|
+
File.unlink unix_path if @unix_paths.include?(unix_path) && File.exist?(unix_path)
|
459
|
+
rescue Errno::EBADF
|
460
|
+
end
|
459
461
|
end
|
460
462
|
end
|
461
463
|
|
data/lib/puma/cli.rb
CHANGED
File without changes
|
data/lib/puma/client.rb
CHANGED
@@ -49,7 +49,8 @@ module Puma
|
|
49
49
|
|
50
50
|
# chunked body validation
|
51
51
|
CHUNK_SIZE_INVALID = /[^\h]/.freeze
|
52
|
-
CHUNK_VALID_ENDING =
|
52
|
+
CHUNK_VALID_ENDING = Const::LINE_END
|
53
|
+
CHUNK_VALID_ENDING_SIZE = CHUNK_VALID_ENDING.bytesize
|
53
54
|
|
54
55
|
# Content-Length header value validation
|
55
56
|
CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze
|
@@ -68,7 +69,7 @@ module Puma
|
|
68
69
|
@to_io = io.to_io
|
69
70
|
@io_buffer = IOBuffer.new
|
70
71
|
@proto_env = env
|
71
|
-
@env = env
|
72
|
+
@env = env&.dup
|
72
73
|
|
73
74
|
@parser = HttpParser.new
|
74
75
|
@parsed_bytes = 0
|
@@ -99,7 +100,8 @@ module Puma
|
|
99
100
|
|
100
101
|
@in_last_chunk = false
|
101
102
|
|
102
|
-
|
103
|
+
# need unfrozen ASCII-8BIT, +'' is UTF-8
|
104
|
+
@read_buffer = String.new # rubocop: disable Performance/UnfreezeString
|
103
105
|
end
|
104
106
|
|
105
107
|
attr_reader :env, :to_io, :body, :io, :timeout_at, :ready, :hijacked,
|
@@ -381,8 +383,8 @@ module Puma
|
|
381
383
|
cl = @env[CONTENT_LENGTH]
|
382
384
|
|
383
385
|
if cl
|
384
|
-
# cannot contain characters that are not \d
|
385
|
-
if CONTENT_LENGTH_VALUE_INVALID.match? cl
|
386
|
+
# cannot contain characters that are not \d, or be empty
|
387
|
+
if CONTENT_LENGTH_VALUE_INVALID.match?(cl) || cl.empty?
|
386
388
|
raise HttpParserError, "Invalid Content-Length: #{cl.inspect}"
|
387
389
|
end
|
388
390
|
else
|
@@ -543,7 +545,7 @@ module Puma
|
|
543
545
|
|
544
546
|
while !io.eof?
|
545
547
|
line = io.gets
|
546
|
-
if line.end_with?(
|
548
|
+
if line.end_with?(CHUNK_VALID_ENDING)
|
547
549
|
# Puma doesn't process chunk extensions, but should parse if they're
|
548
550
|
# present, which is the reason for the semicolon regex
|
549
551
|
chunk_hex = line.strip[/\A[^;]+/]
|
@@ -555,13 +557,19 @@ module Puma
|
|
555
557
|
@in_last_chunk = true
|
556
558
|
@body.rewind
|
557
559
|
rest = io.read
|
558
|
-
|
559
|
-
if rest.bytesize < last_crlf_size
|
560
|
+
if rest.bytesize < CHUNK_VALID_ENDING_SIZE
|
560
561
|
@buffer = nil
|
561
|
-
@partial_part_left =
|
562
|
+
@partial_part_left = CHUNK_VALID_ENDING_SIZE - rest.bytesize
|
562
563
|
return false
|
563
564
|
else
|
564
|
-
|
565
|
+
# if the next character is a CRLF, set buffer to everything after that CRLF
|
566
|
+
start_of_rest = if rest.start_with?(CHUNK_VALID_ENDING)
|
567
|
+
CHUNK_VALID_ENDING_SIZE
|
568
|
+
else # we have started a trailer section, which we do not support. skip it!
|
569
|
+
rest.index(CHUNK_VALID_ENDING*2) + CHUNK_VALID_ENDING_SIZE*2
|
570
|
+
end
|
571
|
+
|
572
|
+
@buffer = rest[start_of_rest..-1]
|
565
573
|
@buffer = nil if @buffer.empty?
|
566
574
|
set_ready
|
567
575
|
return true
|
data/lib/puma/cluster/worker.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/cluster.rb
CHANGED
File without changes
|
data/lib/puma/commonlogger.rb
CHANGED
File without changes
|
data/lib/puma/configuration.rb
CHANGED
File without changes
|
data/lib/puma/const.rb
CHANGED
@@ -18,6 +18,7 @@ module Puma
|
|
18
18
|
100 => 'Continue',
|
19
19
|
101 => 'Switching Protocols',
|
20
20
|
102 => 'Processing',
|
21
|
+
103 => 'Early Hints',
|
21
22
|
200 => 'OK',
|
22
23
|
201 => 'Created',
|
23
24
|
202 => 'Accepted',
|
@@ -49,16 +50,16 @@ module Puma
|
|
49
50
|
410 => 'Gone',
|
50
51
|
411 => 'Length Required',
|
51
52
|
412 => 'Precondition Failed',
|
52
|
-
413 => '
|
53
|
+
413 => 'Content Too Large',
|
53
54
|
414 => 'URI Too Long',
|
54
55
|
415 => 'Unsupported Media Type',
|
55
56
|
416 => 'Range Not Satisfiable',
|
56
57
|
417 => 'Expectation Failed',
|
57
|
-
418 => 'I\'m A Teapot',
|
58
58
|
421 => 'Misdirected Request',
|
59
|
-
422 => 'Unprocessable
|
59
|
+
422 => 'Unprocessable Content',
|
60
60
|
423 => 'Locked',
|
61
61
|
424 => 'Failed Dependency',
|
62
|
+
425 => 'Too Early',
|
62
63
|
426 => 'Upgrade Required',
|
63
64
|
428 => 'Precondition Required',
|
64
65
|
429 => 'Too Many Requests',
|
@@ -73,7 +74,7 @@ module Puma
|
|
73
74
|
506 => 'Variant Also Negotiates',
|
74
75
|
507 => 'Insufficient Storage',
|
75
76
|
508 => 'Loop Detected',
|
76
|
-
510 => 'Not Extended',
|
77
|
+
510 => 'Not Extended (OBSOLETED)',
|
77
78
|
511 => 'Network Authentication Required'
|
78
79
|
}.freeze
|
79
80
|
|
@@ -99,8 +100,8 @@ module Puma
|
|
99
100
|
# too taxing on performance.
|
100
101
|
module Const
|
101
102
|
|
102
|
-
PUMA_VERSION = VERSION = "6.
|
103
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "6.3.1"
|
104
|
+
CODE_NAME = "Mugi No Toki Itaru"
|
104
105
|
|
105
106
|
PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
|
106
107
|
|
@@ -124,15 +125,15 @@ module Puma
|
|
124
125
|
# Indicate that we couldn't parse the request
|
125
126
|
400 => "HTTP/1.1 400 Bad Request\r\n\r\n",
|
126
127
|
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
127
|
-
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\
|
128
|
+
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n",
|
128
129
|
# The standard empty 408 response for requests that timed out.
|
129
|
-
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\
|
130
|
+
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n",
|
130
131
|
# Indicate that there was an internal error, obviously.
|
131
132
|
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n",
|
132
133
|
# Incorrect or invalid header value
|
133
134
|
501 => "HTTP/1.1 501 Not Implemented\r\n\r\n",
|
134
135
|
# A common header for indicating the server is too busy. Not used yet.
|
135
|
-
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\
|
136
|
+
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\n"
|
136
137
|
}.freeze
|
137
138
|
|
138
139
|
# The basic max request size we'll try to read.
|
@@ -147,7 +148,55 @@ module Puma
|
|
147
148
|
|
148
149
|
REQUEST_METHOD = "REQUEST_METHOD"
|
149
150
|
HEAD = "HEAD"
|
151
|
+
|
152
|
+
# based on https://www.rfc-editor.org/rfc/rfc9110.html#name-overview,
|
153
|
+
# with CONNECT removed, and PATCH added
|
150
154
|
SUPPORTED_HTTP_METHODS = %w[HEAD GET POST PUT DELETE OPTIONS TRACE PATCH].freeze
|
155
|
+
|
156
|
+
# list from https://www.iana.org/assignments/http-methods/http-methods.xhtml
|
157
|
+
# as of 04-May-23
|
158
|
+
IANA_HTTP_METHODS = %w[
|
159
|
+
ACL
|
160
|
+
BASELINE-CONTROL
|
161
|
+
BIND
|
162
|
+
CHECKIN
|
163
|
+
CHECKOUT
|
164
|
+
CONNECT
|
165
|
+
COPY
|
166
|
+
DELETE
|
167
|
+
GET
|
168
|
+
HEAD
|
169
|
+
LABEL
|
170
|
+
LINK
|
171
|
+
LOCK
|
172
|
+
MERGE
|
173
|
+
MKACTIVITY
|
174
|
+
MKCALENDAR
|
175
|
+
MKCOL
|
176
|
+
MKREDIRECTREF
|
177
|
+
MKWORKSPACE
|
178
|
+
MOVE
|
179
|
+
OPTIONS
|
180
|
+
ORDERPATCH
|
181
|
+
PATCH
|
182
|
+
POST
|
183
|
+
PRI
|
184
|
+
PROPFIND
|
185
|
+
PROPPATCH
|
186
|
+
PUT
|
187
|
+
REBIND
|
188
|
+
REPORT
|
189
|
+
SEARCH
|
190
|
+
TRACE
|
191
|
+
UNBIND
|
192
|
+
UNCHECKOUT
|
193
|
+
UNLINK
|
194
|
+
UNLOCK
|
195
|
+
UPDATE
|
196
|
+
UPDATEREDIRECTREF
|
197
|
+
VERSION-CONTROL
|
198
|
+
].freeze
|
199
|
+
|
151
200
|
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
152
201
|
LINE_END = "\r\n"
|
153
202
|
REMOTE_ADDR = "REMOTE_ADDR"
|
data/lib/puma/control_cli.rb
CHANGED
File without changes
|
data/lib/puma/detect.rb
CHANGED
File without changes
|
data/lib/puma/dsl.rb
CHANGED
@@ -89,6 +89,7 @@ module Puma
|
|
89
89
|
|
90
90
|
cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil
|
91
91
|
key_flags = (key = opts[:key]) ? "&key=#{Puma::Util.escape(key)}" : nil
|
92
|
+
password_flags = (password_command = opts[:key_password_command]) ? "&key_password_command=#{Puma::Util.escape(password_command)}" : nil
|
92
93
|
|
93
94
|
reuse_flag =
|
94
95
|
if (reuse = opts[:reuse])
|
@@ -114,7 +115,7 @@ module Puma
|
|
114
115
|
nil
|
115
116
|
end
|
116
117
|
|
117
|
-
"ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{ssl_cipher_filter}" \
|
118
|
+
"ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}" \
|
118
119
|
"#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}#{low_latency_str}"
|
119
120
|
end
|
120
121
|
end
|
@@ -1066,6 +1067,38 @@ module Puma
|
|
1066
1067
|
@options[:http_content_length_limit] = limit
|
1067
1068
|
end
|
1068
1069
|
|
1070
|
+
# Supported http methods, which will replace `Puma::Const::SUPPORTED_HTTP_METHODS`.
|
1071
|
+
# The value of `:any` will allows all methods, otherwise, the value must be
|
1072
|
+
# an array of strings. Note that methods are all uppercase.
|
1073
|
+
#
|
1074
|
+
# `Puma::Const::SUPPORTED_HTTP_METHODS` is conservative, if you want a
|
1075
|
+
# complete set of methods, the methods defined by the
|
1076
|
+
# [IANA Method Registry](https://www.iana.org/assignments/http-methods/http-methods.xhtml)
|
1077
|
+
# are pre-defined as the constant `Puma::Const::IANA_HTTP_METHODS`.
|
1078
|
+
#
|
1079
|
+
# @note If the `methods` value is `:any`, no method check with be performed,
|
1080
|
+
# similar to Puma v5 and earlier.
|
1081
|
+
#
|
1082
|
+
# @example Adds 'PROPFIND' to existing supported methods
|
1083
|
+
# supported_http_methods(Puma::Const::SUPPORTED_HTTP_METHODS + ['PROPFIND'])
|
1084
|
+
# @example Restricts methods to the array elements
|
1085
|
+
# supported_http_methods %w[HEAD GET POST PUT DELETE OPTIONS PROPFIND]
|
1086
|
+
# @example Restricts methods to the methods in the IANA Registry
|
1087
|
+
# supported_http_methods Puma::Const::IANA_HTTP_METHODS
|
1088
|
+
# @example Allows any method
|
1089
|
+
# supported_http_methods :any
|
1090
|
+
#
|
1091
|
+
def supported_http_methods(methods)
|
1092
|
+
if methods == :any
|
1093
|
+
@options[:supported_http_methods] = :any
|
1094
|
+
elsif Array === methods && methods == (ary = methods.grep(String).uniq) &&
|
1095
|
+
!ary.empty?
|
1096
|
+
@options[:supported_http_methods] = ary
|
1097
|
+
else
|
1098
|
+
raise "supported_http_methods must be ':any' or a unique array of strings"
|
1099
|
+
end
|
1100
|
+
end
|
1101
|
+
|
1069
1102
|
private
|
1070
1103
|
|
1071
1104
|
# To avoid adding cert_pem and key_pem as URI params, we store them on the
|
data/lib/puma/error_logger.rb
CHANGED
File without changes
|
data/lib/puma/events.rb
CHANGED
File without changes
|
data/lib/puma/io_buffer.rb
CHANGED
File without changes
|
data/lib/puma/jruby_restart.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
data/lib/puma/launcher.rb
CHANGED
File without changes
|
data/lib/puma/log_writer.rb
CHANGED
@@ -125,7 +125,7 @@ module Puma
|
|
125
125
|
def ssl_error(error, ssl_socket)
|
126
126
|
peeraddr = ssl_socket.peeraddr.last rescue "<unknown>"
|
127
127
|
peercert = ssl_socket.peercert
|
128
|
-
subject = peercert
|
128
|
+
subject = peercert&.subject
|
129
129
|
@error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}")
|
130
130
|
end
|
131
131
|
|
@@ -38,6 +38,7 @@ module Puma
|
|
38
38
|
|
39
39
|
ctx.key = params['key'] if params['key']
|
40
40
|
ctx.key_pem = params['key_pem'] if params['key_pem']
|
41
|
+
ctx.key_password_command = params['key_password_command'] if params['key_password_command']
|
41
42
|
|
42
43
|
if params['cert'].nil? && params['cert_pem'].nil?
|
43
44
|
log_writer.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
|
data/lib/puma/minissl.rb
CHANGED
@@ -5,6 +5,7 @@ begin
|
|
5
5
|
rescue LoadError
|
6
6
|
end
|
7
7
|
|
8
|
+
require 'open3'
|
8
9
|
# need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3`
|
9
10
|
# use require, see https://github.com/puma/puma/pull/2381
|
10
11
|
require 'puma/puma_http11'
|
@@ -277,6 +278,7 @@ module Puma
|
|
277
278
|
else
|
278
279
|
# non-jruby Context properties
|
279
280
|
attr_reader :key
|
281
|
+
attr_reader :key_password_command
|
280
282
|
attr_reader :cert
|
281
283
|
attr_reader :ca
|
282
284
|
attr_reader :cert_pem
|
@@ -291,6 +293,10 @@ module Puma
|
|
291
293
|
@key = key
|
292
294
|
end
|
293
295
|
|
296
|
+
def key_password_command=(key_password_command)
|
297
|
+
@key_password_command = key_password_command
|
298
|
+
end
|
299
|
+
|
294
300
|
def cert=(cert)
|
295
301
|
check_file cert, 'Cert'
|
296
302
|
@cert = cert
|
@@ -316,6 +322,17 @@ module Puma
|
|
316
322
|
raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
|
317
323
|
end
|
318
324
|
|
325
|
+
# Executes the command to return the password needed to decrypt the key.
|
326
|
+
def key_password
|
327
|
+
raise "Key password command not configured" if @key_password_command.nil?
|
328
|
+
|
329
|
+
stdout_str, stderr_str, status = Open3.capture3(@key_password_command)
|
330
|
+
|
331
|
+
return stdout_str.chomp if status.success?
|
332
|
+
|
333
|
+
raise "Key password failed with code #{status.exitstatus}: #{stderr_str}"
|
334
|
+
end
|
335
|
+
|
319
336
|
# Controls session reuse. Allowed values are as follows:
|
320
337
|
# * 'off' - matches the behavior of Puma 5.6 and earlier. This is included
|
321
338
|
# in case reuse 'on' is made the default in future Puma versions.
|
data/lib/puma/plugin/systemd.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/plugin.rb
CHANGED
File without changes
|
data/lib/puma/rack/builder.rb
CHANGED
@@ -173,7 +173,7 @@ module Puma::Rack
|
|
173
173
|
TOPLEVEL_BINDING, file, 0
|
174
174
|
end
|
175
175
|
|
176
|
-
def initialize(default_app = nil
|
176
|
+
def initialize(default_app = nil, &block)
|
177
177
|
@use, @map, @run, @warmup = [], nil, default_app, nil
|
178
178
|
|
179
179
|
# Conditionally load rack now, so that any rack middlewares,
|
@@ -183,7 +183,7 @@ module Puma::Rack
|
|
183
183
|
rescue LoadError
|
184
184
|
end
|
185
185
|
|
186
|
-
instance_eval(&block) if
|
186
|
+
instance_eval(&block) if block
|
187
187
|
end
|
188
188
|
|
189
189
|
def self.app(default_app = nil, &block)
|
data/lib/puma/rack/urlmap.rb
CHANGED
File without changes
|
data/lib/puma/rack_default.rb
CHANGED
data/lib/puma/reactor.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'queue_close' unless ::Queue.instance_methods.include? :close
|
4
|
-
|
5
3
|
module Puma
|
6
4
|
class UnsupportedBackend < StandardError; end
|
7
5
|
|
@@ -22,10 +20,12 @@ module Puma
|
|
22
20
|
# its timeout elapses, or when the Reactor shuts down.
|
23
21
|
def initialize(backend, &block)
|
24
22
|
require 'nio'
|
25
|
-
|
26
|
-
|
23
|
+
valid_backends = [:auto, *::NIO::Selector.backends]
|
24
|
+
unless valid_backends.include?(backend)
|
25
|
+
raise ArgumentError.new("unsupported IO selector backend: #{backend} (available backends: #{valid_backends.join(', ')})")
|
27
26
|
end
|
28
|
-
|
27
|
+
|
28
|
+
@selector = ::NIO::Selector.new(NIO::Selector.backends.delete(backend))
|
29
29
|
@input = Queue.new
|
30
30
|
@timeouts = []
|
31
31
|
@block = block
|
@@ -67,6 +67,7 @@ module Puma
|
|
67
67
|
private
|
68
68
|
|
69
69
|
def select_loop
|
70
|
+
close_selector = true
|
70
71
|
begin
|
71
72
|
until @input.closed? && @input.empty?
|
72
73
|
# Wakeup any registered object that receives incoming data.
|
@@ -89,11 +90,19 @@ module Puma
|
|
89
90
|
rescue StandardError => e
|
90
91
|
STDERR.puts "Error in reactor loop escaped: #{e.message} (#{e.class})"
|
91
92
|
STDERR.puts e.backtrace
|
92
|
-
|
93
|
+
|
94
|
+
# NoMethodError may be rarely raised when calling @selector.select, which
|
95
|
+
# is odd. Regardless, it may continue for thousands of calls if retried.
|
96
|
+
# Also, when it raises, @selector.close also raises an error.
|
97
|
+
if NoMethodError === e
|
98
|
+
close_selector = false
|
99
|
+
else
|
100
|
+
retry
|
101
|
+
end
|
93
102
|
end
|
94
103
|
# Wakeup all remaining objects on shutdown.
|
95
104
|
@timeouts.each(&@block)
|
96
|
-
@selector.close
|
105
|
+
@selector.close if close_selector
|
97
106
|
end
|
98
107
|
|
99
108
|
# Start monitoring the object.
|
data/lib/puma/request.rb
CHANGED
@@ -77,7 +77,9 @@ module Puma
|
|
77
77
|
if @early_hints
|
78
78
|
env[EARLY_HINTS] = lambda { |headers|
|
79
79
|
begin
|
80
|
-
|
80
|
+
unless (str = str_early_hints headers).empty?
|
81
|
+
fast_write_str socket, "HTTP/1.1 103 Early Hints\r\n#{str}\r\n"
|
82
|
+
end
|
81
83
|
rescue ConnectionError => e
|
82
84
|
@log_writer.debug_error e
|
83
85
|
# noop, if we lost the socket we just won't send the early hints
|
@@ -93,7 +95,7 @@ module Puma
|
|
93
95
|
env[RACK_AFTER_REPLY] ||= []
|
94
96
|
|
95
97
|
begin
|
96
|
-
if
|
98
|
+
if @supported_http_methods == :any || @supported_http_methods.key?(env[REQUEST_METHOD])
|
97
99
|
status, headers, app_body = @thread_pool.with_force_shutdown do
|
98
100
|
@app.call(env)
|
99
101
|
end
|
@@ -418,7 +420,11 @@ module Puma
|
|
418
420
|
|
419
421
|
unless env[REQUEST_PATH]
|
420
422
|
# it might be a dumbass full host request header
|
421
|
-
uri =
|
423
|
+
uri = begin
|
424
|
+
URI.parse(env[REQUEST_URI])
|
425
|
+
rescue URI::InvalidURIError
|
426
|
+
raise Puma::HttpParserError
|
427
|
+
end
|
422
428
|
env[REQUEST_PATH] = uri.path
|
423
429
|
|
424
430
|
# A nil env value will cause a LintError (and fatal errors elsewhere),
|
@@ -525,7 +531,7 @@ module Puma
|
|
525
531
|
# @version 5.0.3
|
526
532
|
#
|
527
533
|
def str_early_hints(headers)
|
528
|
-
eh_str = +"
|
534
|
+
eh_str = +""
|
529
535
|
headers.each_pair do |k, vs|
|
530
536
|
next if illegal_header_key?(k)
|
531
537
|
|
@@ -534,11 +540,11 @@ module Puma
|
|
534
540
|
next if illegal_header_value?(v)
|
535
541
|
eh_str << "#{k}: #{v}\r\n"
|
536
542
|
end
|
537
|
-
|
543
|
+
elsif !(vs.to_s.empty? || !illegal_header_value?(vs))
|
538
544
|
eh_str << "#{k}: #{vs}\r\n"
|
539
545
|
end
|
540
546
|
end
|
541
|
-
|
547
|
+
eh_str.freeze
|
542
548
|
end
|
543
549
|
private :str_early_hints
|
544
550
|
|
data/lib/puma/runner.rb
CHANGED
File without changes
|
data/lib/puma/sd_notify.rb
CHANGED
File without changes
|
data/lib/puma/server.rb
CHANGED
@@ -51,7 +51,7 @@ module Puma
|
|
51
51
|
def_delegators :@binder, :add_tcp_listener, :add_ssl_listener,
|
52
52
|
:add_unix_listener, :connected_ports
|
53
53
|
|
54
|
-
|
54
|
+
THREAD_LOCAL_KEY = :puma_server
|
55
55
|
|
56
56
|
# Create a server for the rack app +app+.
|
57
57
|
#
|
@@ -97,6 +97,18 @@ module Puma
|
|
97
97
|
@io_selector_backend = @options[:io_selector_backend]
|
98
98
|
@http_content_length_limit = @options[:http_content_length_limit]
|
99
99
|
|
100
|
+
# make this a hash, since we prefer `key?` over `include?`
|
101
|
+
@supported_http_methods =
|
102
|
+
if @options[:supported_http_methods] == :any
|
103
|
+
:any
|
104
|
+
else
|
105
|
+
if (ary = @options[:supported_http_methods])
|
106
|
+
ary
|
107
|
+
else
|
108
|
+
SUPPORTED_HTTP_METHODS
|
109
|
+
end.sort.product([nil]).to_h.freeze
|
110
|
+
end
|
111
|
+
|
100
112
|
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
101
113
|
@leak_stack_on_error = @options[:environment] ? temp : true
|
102
114
|
|
@@ -118,7 +130,7 @@ module Puma
|
|
118
130
|
class << self
|
119
131
|
# @!attribute [r] current
|
120
132
|
def current
|
121
|
-
Thread.current[
|
133
|
+
Thread.current[THREAD_LOCAL_KEY]
|
122
134
|
end
|
123
135
|
|
124
136
|
# :nodoc:
|
@@ -404,7 +416,7 @@ module Puma
|
|
404
416
|
# Return true if one or more requests were processed.
|
405
417
|
def process_client(client)
|
406
418
|
# Advertise this server into the thread
|
407
|
-
Thread.current[
|
419
|
+
Thread.current[THREAD_LOCAL_KEY] = self
|
408
420
|
|
409
421
|
clean_thread_locals = @options[:clean_thread_locals]
|
410
422
|
close_socket = true
|
@@ -566,7 +578,7 @@ module Puma
|
|
566
578
|
|
567
579
|
def notify_safely(message)
|
568
580
|
@notify << message
|
569
|
-
rescue IOError, NoMethodError, Errno::EPIPE
|
581
|
+
rescue IOError, NoMethodError, Errno::EPIPE, Errno::EBADF
|
570
582
|
# The server, in another thread, is shutting down
|
571
583
|
Puma::Util.purge_interrupt_queue
|
572
584
|
rescue RuntimeError => e
|
data/lib/puma/single.rb
CHANGED
File without changes
|
data/lib/puma/state_file.rb
CHANGED
File without changes
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -44,6 +44,10 @@ module Puma
|
|
44
44
|
@name = name
|
45
45
|
@min = Integer(options[:min_threads])
|
46
46
|
@max = Integer(options[:max_threads])
|
47
|
+
# Not an 'exposed' option, options[:pool_shutdown_grace_time] is used in CI
|
48
|
+
# to shorten @shutdown_grace_time from SHUTDOWN_GRACE_TIME. Parallel CI
|
49
|
+
# makes stubbing constants difficult.
|
50
|
+
@shutdown_grace_time = Float(options[:pool_shutdown_grace_time] || SHUTDOWN_GRACE_TIME)
|
47
51
|
@block = block
|
48
52
|
@out_of_band = options[:out_of_band]
|
49
53
|
@clean_thread_locals = options[:clean_thread_locals]
|
@@ -344,8 +348,8 @@ module Puma
|
|
344
348
|
|
345
349
|
# Tell all threads in the pool to exit and wait for them to finish.
|
346
350
|
# Wait +timeout+ seconds then raise +ForceShutdown+ in remaining threads.
|
347
|
-
# Next, wait an extra +
|
348
|
-
# Finally, wait
|
351
|
+
# Next, wait an extra +@shutdown_grace_time+ seconds then force-kill remaining
|
352
|
+
# threads. Finally, wait 1 second for remaining threads to exit.
|
349
353
|
#
|
350
354
|
def shutdown(timeout=-1)
|
351
355
|
threads = with_mutex do
|
@@ -382,7 +386,7 @@ module Puma
|
|
382
386
|
t.raise ForceShutdown if t[:with_force_shutdown]
|
383
387
|
end
|
384
388
|
end
|
385
|
-
join.call(
|
389
|
+
join.call(@shutdown_grace_time)
|
386
390
|
|
387
391
|
# If threads are _still_ running, forcefully kill them and wait to finish.
|
388
392
|
threads.each(&:kill)
|
data/lib/puma/util.rb
CHANGED
File without changes
|
data/lib/puma.rb
CHANGED
File without changes
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -31,7 +31,11 @@ module Puma
|
|
31
31
|
|
32
32
|
conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
|
33
33
|
if options.delete(:Verbose)
|
34
|
-
|
34
|
+
begin
|
35
|
+
require 'rack/commonlogger' # Rack 1.x
|
36
|
+
rescue LoadError
|
37
|
+
require 'rack/common_logger' # Rack 2 and later
|
38
|
+
end
|
35
39
|
app = ::Rack::CommonLogger.new(app, STDOUT)
|
36
40
|
end
|
37
41
|
|
@@ -123,7 +127,7 @@ if Object.const_defined? :Rackup
|
|
123
127
|
end
|
124
128
|
end
|
125
129
|
else
|
126
|
-
do_register = Object.const_defined?(:Rack) && Rack
|
130
|
+
do_register = Object.const_defined?(:Rack) && Rack.release < '3'
|
127
131
|
module Rack
|
128
132
|
module Handler
|
129
133
|
module Puma
|
data/tools/Dockerfile
CHANGED
File without changes
|
data/tools/trickletest.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
@@ -145,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.4.12
|
149
149
|
signing_key:
|
150
150
|
specification_version: 4
|
151
151
|
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|