puma 5.6.6-java → 6.0.0-java
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 +97 -14
- data/LICENSE +0 -0
- data/README.md +21 -17
- data/bin/puma-wild +1 -1
- data/docs/architecture.md +0 -0
- data/docs/compile_options.md +34 -0
- data/docs/deployment.md +0 -0
- data/docs/fork_worker.md +1 -3
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +0 -0
- data/docs/jungle/rc.d/README.md +0 -0
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +0 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +0 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +0 -0
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +11 -8
- data/ext/puma_http11/http11_parser.c +1 -1
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +2 -2
- data/ext/puma_http11/http11_parser.rl +2 -2
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +36 -15
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +3 -3
- data/lib/puma/binder.rb +36 -42
- data/lib/puma/cli.rb +11 -17
- data/lib/puma/client.rb +22 -12
- data/lib/puma/cluster/worker.rb +13 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +28 -25
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +74 -58
- data/lib/puma/const.rb +14 -18
- data/lib/puma/control_cli.rb +3 -6
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +93 -52
- data/lib/puma/error_logger.rb +17 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +29 -4
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/json_serialization.rb +0 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +96 -156
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +23 -12
- data/lib/puma/minissl.rb +82 -11
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +4 -4
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +3 -3
- data/lib/puma/request.rb +292 -161
- data/lib/puma/runner.rb +41 -20
- data/lib/puma/server.rb +53 -66
- data/lib/puma/single.rb +10 -10
- data/lib/puma/state_file.rb +1 -4
- data/lib/puma/systemd.rb +3 -2
- data/lib/puma/thread_pool.rb +16 -13
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +10 -9
- data/lib/rack/handler/puma.rb +9 -9
- data/tools/Dockerfile +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +9 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/rack/version_restriction.rb +0 -15
data/lib/puma/configuration.rb
CHANGED
@@ -1,21 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'rack/builder'
|
4
|
+
require_relative 'plugin'
|
5
|
+
require_relative 'const'
|
6
|
+
# note that dsl is loaded at end of file, requires ConfigDefault constants
|
6
7
|
|
7
8
|
module Puma
|
8
|
-
|
9
|
-
module ConfigDefault
|
10
|
-
DefaultRackup = "config.ru"
|
11
|
-
|
12
|
-
DefaultTCPHost = "0.0.0.0"
|
13
|
-
DefaultTCPPort = 9292
|
14
|
-
DefaultWorkerCheckInterval = 5
|
15
|
-
DefaultWorkerTimeout = 60
|
16
|
-
DefaultWorkerShutdownTimeout = 30
|
17
|
-
end
|
18
|
-
|
19
9
|
# A class used for storing "leveled" configuration options.
|
20
10
|
#
|
21
11
|
# In this class any "user" specified options take precedence over any
|
@@ -136,7 +126,48 @@ module Puma
|
|
136
126
|
# is done because an environment variable may have been modified while loading
|
137
127
|
# configuration files.
|
138
128
|
class Configuration
|
139
|
-
|
129
|
+
DEFAULTS = {
|
130
|
+
auto_trim_time: 30,
|
131
|
+
binds: ['tcp://0.0.0.0:9292'.freeze],
|
132
|
+
clean_thread_locals: false,
|
133
|
+
debug: false,
|
134
|
+
early_hints: nil,
|
135
|
+
environment: 'development'.freeze,
|
136
|
+
# Number of seconds to wait until we get the first data for the request
|
137
|
+
first_data_timeout: 30,
|
138
|
+
io_selector_backend: :auto,
|
139
|
+
log_requests: false,
|
140
|
+
logger: STDOUT,
|
141
|
+
# How many requests to attempt inline before sending a client back to
|
142
|
+
# the reactor to be subject to normal ordering. The idea here is that
|
143
|
+
# we amortize the cost of going back to the reactor for a well behaved
|
144
|
+
# but very "greedy" client across 10 requests. This prevents a not
|
145
|
+
# well behaved client from monopolizing the thread forever.
|
146
|
+
max_fast_inline: 10,
|
147
|
+
max_threads: Puma.mri? ? 5 : 16,
|
148
|
+
min_threads: 0,
|
149
|
+
mode: :http,
|
150
|
+
mutate_stdout_and_stderr_to_sync_on_write: true,
|
151
|
+
out_of_band: [],
|
152
|
+
# Number of seconds for another request within a persistent session.
|
153
|
+
persistent_timeout: 20,
|
154
|
+
queue_requests: true,
|
155
|
+
rackup: 'config.ru'.freeze,
|
156
|
+
raise_exception_on_sigterm: true,
|
157
|
+
reaping_time: 1,
|
158
|
+
remote_address: :socket,
|
159
|
+
silence_single_worker_warning: false,
|
160
|
+
tag: File.basename(Dir.getwd),
|
161
|
+
tcp_host: '0.0.0.0'.freeze,
|
162
|
+
tcp_port: 9292,
|
163
|
+
wait_for_less_busy_worker: 0.005,
|
164
|
+
worker_boot_timeout: 60,
|
165
|
+
worker_check_interval: 5,
|
166
|
+
worker_culling_strategy: :youngest,
|
167
|
+
worker_shutdown_timeout: 30,
|
168
|
+
worker_timeout: 60,
|
169
|
+
workers: 0,
|
170
|
+
}
|
140
171
|
|
141
172
|
def initialize(user_options={}, default_options = {}, &block)
|
142
173
|
default_options = self.puma_default_options.merge(default_options)
|
@@ -181,37 +212,22 @@ module Puma
|
|
181
212
|
self
|
182
213
|
end
|
183
214
|
|
184
|
-
|
185
|
-
|
186
|
-
|
215
|
+
def puma_default_options
|
216
|
+
defaults = DEFAULTS.dup
|
217
|
+
puma_options_from_env.each { |k,v| defaults[k] = v if v }
|
218
|
+
defaults
|
187
219
|
end
|
188
220
|
|
189
|
-
def
|
221
|
+
def puma_options_from_env
|
222
|
+
min = ENV['PUMA_MIN_THREADS'] || ENV['MIN_THREADS']
|
223
|
+
max = ENV['PUMA_MAX_THREADS'] || ENV['MAX_THREADS']
|
224
|
+
workers = ENV['WEB_CONCURRENCY']
|
225
|
+
|
190
226
|
{
|
191
|
-
:
|
192
|
-
:
|
193
|
-
:
|
194
|
-
:
|
195
|
-
:binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"],
|
196
|
-
:workers => Integer(ENV['WEB_CONCURRENCY'] || 0),
|
197
|
-
:silence_single_worker_warning => false,
|
198
|
-
:mode => :http,
|
199
|
-
:worker_check_interval => DefaultWorkerCheckInterval,
|
200
|
-
:worker_timeout => DefaultWorkerTimeout,
|
201
|
-
:worker_boot_timeout => DefaultWorkerTimeout,
|
202
|
-
:worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
|
203
|
-
:worker_culling_strategy => :youngest,
|
204
|
-
:remote_address => :socket,
|
205
|
-
:tag => method(:infer_tag),
|
206
|
-
:environment => -> { ENV['APP_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development' },
|
207
|
-
:rackup => DefaultRackup,
|
208
|
-
:logger => STDOUT,
|
209
|
-
:persistent_timeout => Const::PERSISTENT_TIMEOUT,
|
210
|
-
:first_data_timeout => Const::FIRST_DATA_TIMEOUT,
|
211
|
-
:raise_exception_on_sigterm => true,
|
212
|
-
:max_fast_inline => Const::MAX_FAST_INLINE,
|
213
|
-
:io_selector_backend => :auto,
|
214
|
-
:mutate_stdout_and_stderr_to_sync_on_write => true,
|
227
|
+
min_threads: min && Integer(min),
|
228
|
+
max_threads: max && Integer(max),
|
229
|
+
workers: workers && Integer(workers),
|
230
|
+
environment: ENV['APP_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'],
|
215
231
|
}
|
216
232
|
end
|
217
233
|
|
@@ -227,7 +243,7 @@ module Puma
|
|
227
243
|
return [] if files == ['-']
|
228
244
|
return files if files.any?
|
229
245
|
|
230
|
-
first_default_file = %W(config/puma/#{
|
246
|
+
first_default_file = %W(config/puma/#{@options[:environment]}.rb config/puma.rb).find do |f|
|
231
247
|
File.exist?(f)
|
232
248
|
end
|
233
249
|
|
@@ -270,7 +286,7 @@ module Puma
|
|
270
286
|
found = options[:app] || load_rackup
|
271
287
|
|
272
288
|
if @options[:log_requests]
|
273
|
-
|
289
|
+
require_relative 'commonlogger'
|
274
290
|
logger = @options[:logger]
|
275
291
|
found = CommonLogger.new(found, logger)
|
276
292
|
end
|
@@ -283,21 +299,25 @@ module Puma
|
|
283
299
|
@options[:environment]
|
284
300
|
end
|
285
301
|
|
286
|
-
def environment_str
|
287
|
-
environment.respond_to?(:call) ? environment.call : environment
|
288
|
-
end
|
289
|
-
|
290
302
|
def load_plugin(name)
|
291
303
|
@plugins.create name
|
292
304
|
end
|
293
305
|
|
294
|
-
|
306
|
+
# @param key [:Symbol] hook to run
|
307
|
+
# @param arg [Launcher, Int] `:on_restart` passes Launcher
|
308
|
+
#
|
309
|
+
def run_hooks(key, arg, log_writer, hook_data = nil)
|
295
310
|
@options.all_of(key).each do |b|
|
296
311
|
begin
|
297
|
-
b
|
312
|
+
if Array === b
|
313
|
+
hook_data[b[1]] ||= Hash.new
|
314
|
+
b[0].call arg, hook_data[b[1]]
|
315
|
+
else
|
316
|
+
b.call arg
|
317
|
+
end
|
298
318
|
rescue => e
|
299
|
-
|
300
|
-
|
319
|
+
log_writer.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}"
|
320
|
+
log_writer.debug e.backtrace.join("\n")
|
301
321
|
end
|
302
322
|
end
|
303
323
|
end
|
@@ -315,10 +335,6 @@ module Puma
|
|
315
335
|
|
316
336
|
private
|
317
337
|
|
318
|
-
def infer_tag
|
319
|
-
File.basename(Dir.getwd)
|
320
|
-
end
|
321
|
-
|
322
338
|
# Load and use the normal Rack builder if we can, otherwise
|
323
339
|
# fallback to our minimal version.
|
324
340
|
def rack_builder
|
@@ -368,4 +384,4 @@ module Puma
|
|
368
384
|
end
|
369
385
|
end
|
370
386
|
|
371
|
-
|
387
|
+
require_relative 'dsl'
|
data/lib/puma/const.rb
CHANGED
@@ -100,32 +100,17 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "6.0.0".freeze
|
104
|
+
CODE_NAME = "Sunflower".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
107
107
|
|
108
108
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
109
109
|
|
110
|
-
# The default number of seconds for another request within a persistent
|
111
|
-
# session.
|
112
|
-
PERSISTENT_TIMEOUT = 20
|
113
|
-
|
114
|
-
# The default number of seconds to wait until we get the first data
|
115
|
-
# for the request
|
116
|
-
FIRST_DATA_TIMEOUT = 30
|
117
|
-
|
118
110
|
# How long to wait when getting some write blocking on the socket when
|
119
111
|
# sending data back
|
120
112
|
WRITE_TIMEOUT = 10
|
121
113
|
|
122
|
-
# How many requests to attempt inline before sending a client back to
|
123
|
-
# the reactor to be subject to normal ordering. The idea here is that
|
124
|
-
# we amortize the cost of going back to the reactor for a well behaved
|
125
|
-
# but very "greedy" client across 10 requests. This prevents a not
|
126
|
-
# well behaved client from monopolizing the thread forever.
|
127
|
-
MAX_FAST_INLINE = 10
|
128
|
-
|
129
114
|
# The original URI requested by the client.
|
130
115
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
131
116
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
@@ -163,6 +148,14 @@ module Puma
|
|
163
148
|
|
164
149
|
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
165
150
|
HEAD = "HEAD".freeze
|
151
|
+
GET = "GET".freeze
|
152
|
+
POST = "POST".freeze
|
153
|
+
PUT = "PUT".freeze
|
154
|
+
DELETE = "DELETE".freeze
|
155
|
+
OPTIONS = "OPTIONS".freeze
|
156
|
+
TRACE = "TRACE".freeze
|
157
|
+
PATCH = "PATCH".freeze
|
158
|
+
SUPPORTED_HTTP_METHODS = [HEAD, GET, POST, PUT, DELETE, OPTIONS, TRACE, PATCH].freeze
|
166
159
|
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
167
160
|
LINE_END = "\r\n".freeze
|
168
161
|
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
@@ -177,7 +170,10 @@ module Puma
|
|
177
170
|
PORT_80 = "80".freeze
|
178
171
|
PORT_443 = "443".freeze
|
179
172
|
LOCALHOST = "localhost".freeze
|
180
|
-
|
173
|
+
LOCALHOST_IPV4 = "127.0.0.1".freeze
|
174
|
+
LOCALHOST_IPV6 = "::1".freeze
|
175
|
+
UNSPECIFIED_IPV4 = "0.0.0.0".freeze
|
176
|
+
UNSPECIFIED_IPV6 = "::".freeze
|
181
177
|
|
182
178
|
SERVER_PROTOCOL = "SERVER_PROTOCOL".freeze
|
183
179
|
HTTP_11 = "HTTP/1.1".freeze
|
data/lib/puma/control_cli.rb
CHANGED
@@ -33,9 +33,6 @@ module Puma
|
|
33
33
|
'worker-count-up' => 'SIGTTIN'
|
34
34
|
}.freeze
|
35
35
|
|
36
|
-
# @deprecated 6.0.0
|
37
|
-
COMMANDS = CMD_PATH_SIG_MAP.keys.freeze
|
38
|
-
|
39
36
|
# commands that cannot be used in a request
|
40
37
|
NO_REQ_COMMANDS = %w[info reopen-log worker-count-down worker-count-up].freeze
|
41
38
|
|
@@ -287,7 +284,7 @@ module Puma
|
|
287
284
|
|
288
285
|
private
|
289
286
|
def start
|
290
|
-
|
287
|
+
require_relative 'cli'
|
291
288
|
|
292
289
|
run_args = []
|
293
290
|
|
@@ -299,13 +296,13 @@ module Puma
|
|
299
296
|
run_args += ["-C", @config_file] if @config_file
|
300
297
|
run_args += ["-e", @environment] if @environment
|
301
298
|
|
302
|
-
|
299
|
+
log_writer = Puma::LogWriter.new(@stdout, @stderr)
|
303
300
|
|
304
301
|
# replace $0 because puma use it to generate restart command
|
305
302
|
puma_cmd = $0.gsub(/pumactl$/, 'puma')
|
306
303
|
$0 = puma_cmd if File.exist?(puma_cmd)
|
307
304
|
|
308
|
-
cli = Puma::CLI.new run_args,
|
305
|
+
cli = Puma::CLI.new run_args, log_writer
|
309
306
|
cli.run
|
310
307
|
end
|
311
308
|
end
|
data/lib/puma/detect.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative 'const'
|
4
|
+
require_relative 'util'
|
5
5
|
|
6
6
|
module Puma
|
7
7
|
# The methods that are available for use inside the configuration file.
|
@@ -32,8 +32,24 @@ module Puma
|
|
32
32
|
# You can also find many examples being used by the test suite in
|
33
33
|
# +test/config+.
|
34
34
|
#
|
35
|
+
# Puma v6 adds the option to specify a key name (String or Symbol) to the
|
36
|
+
# hooks that run inside the forked workers. All the hooks run inside the
|
37
|
+
# {Puma::Cluster::Worker#run} method.
|
38
|
+
#
|
39
|
+
# Previously, the worker index and the LogWriter instance were passed to the
|
40
|
+
# hook blocks/procs. If a key name is specified, a hash is passed as the last
|
41
|
+
# parameter. This allows storage of data, typically objects that are created
|
42
|
+
# before the worker that need to be passed to the hook when the worker is shutdown.
|
43
|
+
#
|
44
|
+
# The following hooks have been updated:
|
45
|
+
#
|
46
|
+
# | DSL Method | Options Key | Fork Block Location |
|
47
|
+
# | on_worker_boot | :before_worker_boot | inside, before |
|
48
|
+
# | on_worker_shutdown | :before_worker_shutdown | inside, after |
|
49
|
+
# | on_refork | :before_refork | inside |
|
50
|
+
#
|
35
51
|
class DSL
|
36
|
-
|
52
|
+
ON_WORKER_KEY = [String, Symbol].freeze
|
37
53
|
|
38
54
|
# convenience method so logic can be used in CI
|
39
55
|
# @see ssl_bind
|
@@ -52,25 +68,53 @@ module Puma
|
|
52
68
|
backlog_str = opts[:backlog] ? "&backlog=#{Integer(opts[:backlog])}" : ''
|
53
69
|
|
54
70
|
if defined?(JRUBY_VERSION)
|
55
|
-
|
56
|
-
|
71
|
+
cipher_suites = opts[:ssl_cipher_list] ? "&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil # old name
|
72
|
+
cipher_suites = "#{cipher_suites}&cipher_suites=#{opts[:cipher_suites]}" if opts[:cipher_suites]
|
73
|
+
protocols = opts[:protocols] ? "&protocols=#{opts[:protocols]}" : nil
|
57
74
|
|
58
75
|
keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
|
76
|
+
keystore_additions = "#{keystore_additions}&keystore-type=#{opts[:keystore_type]}" if opts[:keystore_type]
|
77
|
+
if opts[:truststore]
|
78
|
+
truststore_additions = "&truststore=#{opts[:truststore]}"
|
79
|
+
truststore_additions = "#{truststore_additions}&truststore-pass=#{opts[:truststore_pass]}" if opts[:truststore_pass]
|
80
|
+
truststore_additions = "#{truststore_additions}&truststore-type=#{opts[:truststore_type]}" if opts[:truststore_type]
|
81
|
+
end
|
59
82
|
|
60
|
-
"ssl://#{host}:#{port}?#{keystore_additions}#{
|
83
|
+
"ssl://#{host}:#{port}?#{keystore_additions}#{truststore_additions}#{cipher_suites}#{protocols}" \
|
61
84
|
"&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}"
|
62
85
|
else
|
63
|
-
ssl_cipher_filter = opts[:ssl_cipher_filter] ?
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
86
|
+
ssl_cipher_filter = opts[:ssl_cipher_filter] ? "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
|
87
|
+
v_flags = (ary = opts[:verification_flags]) ? "&verification_flags=#{Array(ary).join ','}" : nil
|
88
|
+
|
89
|
+
cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil
|
90
|
+
key_flags = (key = opts[:key]) ? "&key=#{Puma::Util.escape(key)}" : nil
|
91
|
+
|
92
|
+
reuse_flag =
|
93
|
+
if (reuse = opts[:reuse])
|
94
|
+
if reuse == true
|
95
|
+
'&reuse=dflt'
|
96
|
+
elsif reuse.is_a?(Hash) && (reuse.key?(:size) || reuse.key?(:timeout))
|
97
|
+
val = +''
|
98
|
+
if (size = reuse[:size]) && Integer === size
|
99
|
+
val << size.to_s
|
100
|
+
end
|
101
|
+
if (timeout = reuse[:timeout]) && Integer === timeout
|
102
|
+
val << ",#{timeout}"
|
103
|
+
end
|
104
|
+
if val.empty?
|
105
|
+
nil
|
106
|
+
else
|
107
|
+
"&reuse=#{val}"
|
108
|
+
end
|
109
|
+
else
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
else
|
113
|
+
nil
|
114
|
+
end
|
71
115
|
|
72
|
-
"ssl://#{host}:#{port}?#{cert_flags}#{key_flags}" \
|
73
|
-
"#{
|
116
|
+
"ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{ssl_cipher_filter}" \
|
117
|
+
"#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}"
|
74
118
|
end
|
75
119
|
end
|
76
120
|
|
@@ -106,7 +150,7 @@ module Puma
|
|
106
150
|
end
|
107
151
|
|
108
152
|
def default_host
|
109
|
-
@options[:default_host] || Configuration::
|
153
|
+
@options[:default_host] || Configuration::DEFAULTS[:tcp_host]
|
110
154
|
end
|
111
155
|
|
112
156
|
def inject(&blk)
|
@@ -452,6 +496,10 @@ module Puma
|
|
452
496
|
# Puma will assume you are using the +localhost+ gem and try to load the
|
453
497
|
# appropriate files.
|
454
498
|
#
|
499
|
+
# When using the options hash parameter, the `reuse:` value is either
|
500
|
+
# `true`, which sets reuse 'on' with default values, or a hash, with `:size`
|
501
|
+
# and/or `:timeout` keys, each with integer values.
|
502
|
+
#
|
455
503
|
# @example
|
456
504
|
# ssl_bind '127.0.0.1', '9292', {
|
457
505
|
# cert: path_to_cert,
|
@@ -459,6 +507,7 @@ module Puma
|
|
459
507
|
# ssl_cipher_filter: cipher_filter, # optional
|
460
508
|
# verify_mode: verify_mode, # default 'none'
|
461
509
|
# verification_flags: flags, # optional, not supported by JRuby
|
510
|
+
# reuse: true # optional
|
462
511
|
# }
|
463
512
|
#
|
464
513
|
# @example Using self-signed certificate with the +localhost+ gem:
|
@@ -468,6 +517,7 @@ module Puma
|
|
468
517
|
# ssl_bind '127.0.0.1', '9292', {
|
469
518
|
# cert_pem: File.read(path_to_cert),
|
470
519
|
# key_pem: File.read(path_to_key),
|
520
|
+
# reuse: {size: 2_000, timeout: 20} # optional
|
471
521
|
# }
|
472
522
|
#
|
473
523
|
# @example For JRuby, two keys are required: +keystore+ & +keystore_pass+
|
@@ -560,9 +610,8 @@ module Puma
|
|
560
610
|
# on_worker_boot do
|
561
611
|
# puts 'Before worker boot...'
|
562
612
|
# end
|
563
|
-
def on_worker_boot(&block)
|
564
|
-
|
565
|
-
@options[:before_worker_boot] << block
|
613
|
+
def on_worker_boot(key = nil, &block)
|
614
|
+
process_hook :before_worker_boot, key, block, 'on_worker_boot'
|
566
615
|
end
|
567
616
|
|
568
617
|
# Code to run immediately before a worker shuts
|
@@ -577,9 +626,8 @@ module Puma
|
|
577
626
|
# on_worker_shutdown do
|
578
627
|
# puts 'On worker shutdown...'
|
579
628
|
# end
|
580
|
-
def on_worker_shutdown(&block)
|
581
|
-
|
582
|
-
@options[:before_worker_shutdown] << block
|
629
|
+
def on_worker_shutdown(key = nil, &block)
|
630
|
+
process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
|
583
631
|
end
|
584
632
|
|
585
633
|
# Code to run in the master right before a worker is started. The worker's
|
@@ -593,8 +641,7 @@ module Puma
|
|
593
641
|
# puts 'Before worker fork...'
|
594
642
|
# end
|
595
643
|
def on_worker_fork(&block)
|
596
|
-
|
597
|
-
@options[:before_worker_fork] << block
|
644
|
+
process_hook :before_worker_fork, nil, block, 'on_worker_fork'
|
598
645
|
end
|
599
646
|
|
600
647
|
# Code to run in the master after a worker has been started. The worker's
|
@@ -608,8 +655,7 @@ module Puma
|
|
608
655
|
# puts 'After worker fork...'
|
609
656
|
# end
|
610
657
|
def after_worker_fork(&block)
|
611
|
-
|
612
|
-
@options[:after_worker_fork] << block
|
658
|
+
process_hook :after_worker_fork, nil, block, 'after_worker_fork'
|
613
659
|
end
|
614
660
|
|
615
661
|
alias_method :after_worker_boot, :after_worker_fork
|
@@ -632,9 +678,8 @@ module Puma
|
|
632
678
|
# end
|
633
679
|
# @version 5.0.0
|
634
680
|
#
|
635
|
-
def on_refork(&block)
|
636
|
-
|
637
|
-
@options[:before_refork] << block
|
681
|
+
def on_refork(key = nil, &block)
|
682
|
+
process_hook :before_refork, key, block, 'on_refork'
|
638
683
|
end
|
639
684
|
|
640
685
|
# Code to run out-of-band when the worker is idle.
|
@@ -647,8 +692,7 @@ module Puma
|
|
647
692
|
#
|
648
693
|
# This can be called multiple times to add several hooks.
|
649
694
|
def out_of_band(&block)
|
650
|
-
|
651
|
-
@options[:out_of_band] << block
|
695
|
+
process_hook :out_of_band, nil, block, 'out_of_band'
|
652
696
|
end
|
653
697
|
|
654
698
|
# The directory to operate out of.
|
@@ -778,7 +822,7 @@ module Puma
|
|
778
822
|
#
|
779
823
|
def worker_timeout(timeout)
|
780
824
|
timeout = Integer(timeout)
|
781
|
-
min = @options.fetch(:worker_check_interval,
|
825
|
+
min = @options.fetch(:worker_check_interval, Configuration::DEFAULTS[:worker_check_interval])
|
782
826
|
|
783
827
|
if timeout <= min
|
784
828
|
raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})"
|
@@ -882,13 +926,16 @@ module Puma
|
|
882
926
|
# There are 5 possible values:
|
883
927
|
#
|
884
928
|
# 1. **:socket** (the default) - read the peername from the socket using the
|
885
|
-
# syscall. This is the normal behavior.
|
929
|
+
# syscall. This is the normal behavior. If this fails for any reason (e.g.,
|
930
|
+
# if the peer disconnects between the connection being accepted and the getpeername
|
931
|
+
# system call), Puma will return "0.0.0.0"
|
886
932
|
# 2. **:localhost** - set the remote address to "127.0.0.1"
|
887
933
|
# 3. **header: <http_header>**- set the remote address to the value of the
|
888
934
|
# provided http header. For instance:
|
889
935
|
# `set_remote_address header: "X-Real-IP"`.
|
890
936
|
# Only the first word (as separated by spaces or comma) is used, allowing
|
891
|
-
# headers such as X-Forwarded-For to be used as well.
|
937
|
+
# headers such as X-Forwarded-For to be used as well. If this header is absent,
|
938
|
+
# Puma will fall back to the behavior of :socket
|
892
939
|
# 4. **proxy_protocol: :v1**- set the remote address to the value read from the
|
893
940
|
# HAproxy PROXY protocol, version 1. If the request does not have the PROXY
|
894
941
|
# protocol attached to it, will fall back to :socket
|
@@ -942,23 +989,6 @@ module Puma
|
|
942
989
|
@options[:fork_worker] = Integer(after_requests)
|
943
990
|
end
|
944
991
|
|
945
|
-
# When enabled, Puma will GC 4 times before forking workers.
|
946
|
-
# If available (Ruby 2.7+), we will also call GC.compact.
|
947
|
-
# Not recommended for non-MRI Rubies.
|
948
|
-
#
|
949
|
-
# Based on the work of Koichi Sasada and Aaron Patterson, this option may
|
950
|
-
# decrease memory utilization of preload-enabled cluster-mode Pumas. It will
|
951
|
-
# also increase time to boot and fork. See your logs for details on how much
|
952
|
-
# time this adds to your boot process. For most apps, it will be less than one
|
953
|
-
# second.
|
954
|
-
#
|
955
|
-
# @see Puma::Cluster#nakayoshi_gc
|
956
|
-
# @version 5.0.0
|
957
|
-
#
|
958
|
-
def nakayoshi_fork(enabled=true)
|
959
|
-
@options[:nakayoshi_fork] = enabled
|
960
|
-
end
|
961
|
-
|
962
992
|
# The number of requests to attempt inline before sending a client back to
|
963
993
|
# the reactor to be subject to normal ordering.
|
964
994
|
#
|
@@ -1008,5 +1038,16 @@ module Puma
|
|
1008
1038
|
end
|
1009
1039
|
end
|
1010
1040
|
end
|
1041
|
+
|
1042
|
+
def process_hook(options_key, key, block, meth)
|
1043
|
+
@options[options_key] ||= []
|
1044
|
+
if ON_WORKER_KEY.include? key.class
|
1045
|
+
@options[options_key] << [block, key.to_sym]
|
1046
|
+
elsif key.nil?
|
1047
|
+
@options[options_key] << block
|
1048
|
+
else
|
1049
|
+
raise "'#{method}' key must be String or Symbol"
|
1050
|
+
end
|
1051
|
+
end
|
1011
1052
|
end
|
1012
1053
|
end
|
data/lib/puma/error_logger.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'const'
|
4
4
|
|
5
5
|
module Puma
|
6
6
|
# The implementation of a detailed error logging.
|
@@ -13,6 +13,8 @@ module Puma
|
|
13
13
|
|
14
14
|
REQUEST_FORMAT = %{"%s %s%s" - (%s)}
|
15
15
|
|
16
|
+
LOG_QUEUE = Queue.new
|
17
|
+
|
16
18
|
def initialize(ioerr)
|
17
19
|
@ioerr = ioerr
|
18
20
|
|
@@ -31,7 +33,7 @@ module Puma
|
|
31
33
|
# and before all remaining info.
|
32
34
|
#
|
33
35
|
def info(options={})
|
34
|
-
|
36
|
+
internal_write title(options)
|
35
37
|
end
|
36
38
|
|
37
39
|
# Print occurred error details only if
|
@@ -53,7 +55,7 @@ module Puma
|
|
53
55
|
string_block << request_dump(req) if request_parsed?(req)
|
54
56
|
string_block << error.backtrace if error
|
55
57
|
|
56
|
-
|
58
|
+
internal_write string_block.join("\n")
|
57
59
|
end
|
58
60
|
|
59
61
|
def title(options={})
|
@@ -93,12 +95,18 @@ module Puma
|
|
93
95
|
req && req.env[REQUEST_METHOD]
|
94
96
|
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
98
|
+
def internal_write(str)
|
99
|
+
LOG_QUEUE << str
|
100
|
+
while (w_str = LOG_QUEUE.pop(true)) do
|
101
|
+
begin
|
102
|
+
@ioerr.is_a?(IO) and @ioerr.wait_writable(1)
|
103
|
+
@ioerr.write "#{w_str}\n"
|
104
|
+
@ioerr.flush unless @ioerr.sync
|
105
|
+
rescue Errno::EPIPE, Errno::EBADF, IOError
|
106
|
+
end
|
107
|
+
end
|
108
|
+
rescue ThreadError
|
102
109
|
end
|
110
|
+
private :internal_write
|
103
111
|
end
|
104
112
|
end
|