puma 6.1.1 → 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 +76 -1
- data/LICENSE +0 -0
- data/README.md +39 -4
- 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 +1 -1
- 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 +21 -14
- data/lib/puma/configuration.rb +1 -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 +78 -2
- data/lib/puma/error_logger.rb +2 -1
- 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 +2 -0
- data/lib/puma/log_writer.rb +10 -4
- 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 +64 -48
- 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 +12 -6
- data/tools/Dockerfile +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +2 -2
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
|
@@ -419,6 +420,11 @@ module Puma
|
|
419
420
|
@options[:log_requests] = which
|
420
421
|
end
|
421
422
|
|
423
|
+
# Pass in a custom logging class instance
|
424
|
+
def custom_logger(custom_logger)
|
425
|
+
@options[:custom_logger] = custom_logger
|
426
|
+
end
|
427
|
+
|
422
428
|
# Show debugging info
|
423
429
|
#
|
424
430
|
def debug
|
@@ -585,6 +591,11 @@ module Puma
|
|
585
591
|
@options[:silence_single_worker_warning] = true
|
586
592
|
end
|
587
593
|
|
594
|
+
# Disable warning message when running single mode with callback hook defined.
|
595
|
+
def silence_fork_callback_warning
|
596
|
+
@options[:silence_fork_callback_warning] = true
|
597
|
+
end
|
598
|
+
|
588
599
|
# Code to run immediately before master process
|
589
600
|
# forks workers (once on boot). These hooks can block if necessary
|
590
601
|
# to wait for background operations unknown to Puma to finish before
|
@@ -600,6 +611,8 @@ module Puma
|
|
600
611
|
# puts "Starting workers..."
|
601
612
|
# end
|
602
613
|
def before_fork(&block)
|
614
|
+
warn_if_in_single_mode('before_fork')
|
615
|
+
|
603
616
|
@options[:before_fork] ||= []
|
604
617
|
@options[:before_fork] << block
|
605
618
|
end
|
@@ -615,6 +628,8 @@ module Puma
|
|
615
628
|
# puts 'Before worker boot...'
|
616
629
|
# end
|
617
630
|
def on_worker_boot(key = nil, &block)
|
631
|
+
warn_if_in_single_mode('on_worker_boot')
|
632
|
+
|
618
633
|
process_hook :before_worker_boot, key, block, 'on_worker_boot'
|
619
634
|
end
|
620
635
|
|
@@ -631,6 +646,8 @@ module Puma
|
|
631
646
|
# puts 'On worker shutdown...'
|
632
647
|
# end
|
633
648
|
def on_worker_shutdown(key = nil, &block)
|
649
|
+
warn_if_in_single_mode('on_worker_shutdown')
|
650
|
+
|
634
651
|
process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
|
635
652
|
end
|
636
653
|
|
@@ -645,6 +662,8 @@ module Puma
|
|
645
662
|
# puts 'Before worker fork...'
|
646
663
|
# end
|
647
664
|
def on_worker_fork(&block)
|
665
|
+
warn_if_in_single_mode('on_worker_fork')
|
666
|
+
|
648
667
|
process_hook :before_worker_fork, nil, block, 'on_worker_fork'
|
649
668
|
end
|
650
669
|
|
@@ -659,11 +678,23 @@ module Puma
|
|
659
678
|
# puts 'After worker fork...'
|
660
679
|
# end
|
661
680
|
def after_worker_fork(&block)
|
681
|
+
warn_if_in_single_mode('after_worker_fork')
|
682
|
+
|
662
683
|
process_hook :after_worker_fork, nil, block, 'after_worker_fork'
|
663
684
|
end
|
664
685
|
|
665
686
|
alias_method :after_worker_boot, :after_worker_fork
|
666
687
|
|
688
|
+
# Code to run after puma is booted (works for both: single and clustered)
|
689
|
+
#
|
690
|
+
# @example
|
691
|
+
# on_booted do
|
692
|
+
# puts 'After booting...'
|
693
|
+
# end
|
694
|
+
def on_booted(&block)
|
695
|
+
@config.options[:events].on_booted(&block)
|
696
|
+
end
|
697
|
+
|
667
698
|
# When `fork_worker` is enabled, code to run in Worker 0
|
668
699
|
# before all other workers are re-forked from this process,
|
669
700
|
# after the server has temporarily stopped serving requests
|
@@ -1036,6 +1067,38 @@ module Puma
|
|
1036
1067
|
@options[:http_content_length_limit] = limit
|
1037
1068
|
end
|
1038
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
|
+
|
1039
1102
|
private
|
1040
1103
|
|
1041
1104
|
# To avoid adding cert_pem and key_pem as URI params, we store them on the
|
@@ -1063,7 +1126,20 @@ module Puma
|
|
1063
1126
|
elsif key.nil?
|
1064
1127
|
@options[options_key] << block
|
1065
1128
|
else
|
1066
|
-
raise "'#{
|
1129
|
+
raise "'#{meth}' key must be String or Symbol"
|
1130
|
+
end
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def warn_if_in_single_mode(hook_name)
|
1134
|
+
return if @options[:silence_fork_callback_warning]
|
1135
|
+
|
1136
|
+
if (@options[:workers] || 0) == 0
|
1137
|
+
log_string =
|
1138
|
+
"Warning: You specified code to run in a `#{hook_name}` block, " \
|
1139
|
+
"but Puma is not configured to run in cluster mode (worker count > 0 ), " \
|
1140
|
+
"so your `#{hook_name}` block did not run"
|
1141
|
+
|
1142
|
+
LogWriter.stdio.log(log_string)
|
1067
1143
|
end
|
1068
1144
|
end
|
1069
1145
|
end
|
data/lib/puma/error_logger.rb
CHANGED
@@ -102,7 +102,8 @@ module Puma
|
|
102
102
|
@ioerr.is_a?(IO) and @ioerr.wait_writable(1)
|
103
103
|
@ioerr.write "#{w_str}\n"
|
104
104
|
@ioerr.flush unless @ioerr.sync
|
105
|
-
rescue Errno::EPIPE, Errno::EBADF, IOError
|
105
|
+
rescue Errno::EPIPE, Errno::EBADF, IOError, Errno::EINVAL
|
106
|
+
# 'Invalid argument' (Errno::EINVAL) may be raised by flush
|
106
107
|
end
|
107
108
|
end
|
108
109
|
rescue ThreadError
|
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
@@ -79,6 +79,8 @@ module Puma
|
|
79
79
|
@log_writer.formatter = LogWriter::PidFormatter.new if clustered?
|
80
80
|
@log_writer.formatter = options[:log_formatter] if @options[:log_formatter]
|
81
81
|
|
82
|
+
@log_writer.custom_logger = options[:custom_logger] if @options[:custom_logger]
|
83
|
+
|
82
84
|
generate_restart_data
|
83
85
|
|
84
86
|
if clustered? && !Puma.forkable?
|
data/lib/puma/log_writer.rb
CHANGED
@@ -28,11 +28,12 @@ module Puma
|
|
28
28
|
attr_reader :stdout,
|
29
29
|
:stderr
|
30
30
|
|
31
|
-
attr_accessor :formatter
|
31
|
+
attr_accessor :formatter, :custom_logger
|
32
32
|
|
33
33
|
# Create a LogWriter that prints to +stdout+ and +stderr+.
|
34
34
|
def initialize(stdout, stderr)
|
35
35
|
@formatter = DefaultFormatter.new
|
36
|
+
@custom_logger = nil
|
36
37
|
@stdout = stdout
|
37
38
|
@stderr = stderr
|
38
39
|
|
@@ -59,7 +60,11 @@ module Puma
|
|
59
60
|
|
60
61
|
# Write +str+ to +@stdout+
|
61
62
|
def log(str)
|
62
|
-
|
63
|
+
if @custom_logger&.respond_to?(:write)
|
64
|
+
@custom_logger.write(format(str))
|
65
|
+
else
|
66
|
+
internal_write "#{@formatter.call str}\n"
|
67
|
+
end
|
63
68
|
end
|
64
69
|
|
65
70
|
def write(str)
|
@@ -73,7 +78,8 @@ module Puma
|
|
73
78
|
@stdout.is_a?(IO) and @stdout.wait_writable(1)
|
74
79
|
@stdout.write w_str
|
75
80
|
@stdout.flush unless @stdout.sync
|
76
|
-
rescue Errno::EPIPE, Errno::EBADF, IOError
|
81
|
+
rescue Errno::EPIPE, Errno::EBADF, IOError, Errno::EINVAL
|
82
|
+
# 'Invalid argument' (Errno::EINVAL) may be raised by flush
|
77
83
|
end
|
78
84
|
end
|
79
85
|
rescue ThreadError
|
@@ -119,7 +125,7 @@ module Puma
|
|
119
125
|
def ssl_error(error, ssl_socket)
|
120
126
|
peeraddr = ssl_socket.peeraddr.last rescue "<unknown>"
|
121
127
|
peercert = ssl_socket.peercert
|
122
|
-
subject = peercert
|
128
|
+
subject = peercert&.subject
|
123
129
|
@error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}")
|
124
130
|
end
|
125
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.
|