puma 3.9.1 → 4.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 +5 -5
- data/History.md +232 -0
- data/README.md +162 -224
- data/docs/architecture.md +37 -0
- data/{DEPLOYMENT.md → docs/deployment.md} +24 -4
- 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/plugins.md +38 -0
- data/docs/restart.md +41 -0
- data/docs/signals.md +56 -3
- data/docs/systemd.md +130 -37
- data/docs/tcp_mode.md +96 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +13 -0
- data/ext/puma_http11/http11_parser.c +115 -140
- data/ext/puma_http11/http11_parser.java.rl +21 -37
- data/ext/puma_http11/http11_parser.rl +9 -9
- data/ext/puma_http11/http11_parser_common.rl +3 -3
- data/ext/puma_http11/mini_ssl.c +104 -8
- data/ext/puma_http11/org/jruby/puma/Http11.java +106 -114
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +90 -108
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +21 -4
- data/ext/puma_http11/puma_http11.c +2 -0
- data/lib/puma.rb +16 -0
- data/lib/puma/accept_nonblock.rb +7 -1
- data/lib/puma/app/status.rb +40 -26
- data/lib/puma/binder.rb +57 -74
- data/lib/puma/cli.rb +26 -7
- data/lib/puma/client.rb +243 -190
- data/lib/puma/cluster.rb +78 -34
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +24 -16
- data/lib/puma/const.rb +36 -18
- data/lib/puma/control_cli.rb +46 -19
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +329 -68
- data/lib/puma/events.rb +6 -1
- data/lib/puma/io_buffer.rb +3 -6
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/launcher.rb +120 -58
- data/lib/puma/minissl.rb +69 -27
- data/lib/puma/minissl/context_builder.rb +76 -0
- data/lib/puma/null_io.rb +2 -0
- data/lib/puma/plugin.rb +7 -2
- data/lib/puma/plugin/tmp_restart.rb +2 -1
- data/lib/puma/rack/builder.rb +4 -1
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +224 -34
- data/lib/puma/runner.rb +25 -4
- data/lib/puma/server.rb +148 -62
- data/lib/puma/single.rb +16 -5
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +61 -38
- data/lib/puma/util.rb +2 -6
- data/lib/rack/handler/puma.rb +10 -4
- data/tools/docker/Dockerfile +16 -0
- data/tools/jungle/README.md +12 -2
- data/tools/jungle/init.d/README.md +2 -0
- data/tools/jungle/init.d/puma +8 -8
- data/tools/jungle/init.d/run-puma +1 -1
- data/tools/jungle/rc.d/README.md +74 -0
- data/tools/jungle/rc.d/puma +61 -0
- data/tools/jungle/rc.d/puma.conf +10 -0
- data/tools/trickletest.rb +1 -2
- metadata +29 -56
- data/.github/issue_template.md +0 -20
- data/Gemfile +0 -14
- data/Manifest.txt +0 -78
- data/Rakefile +0 -165
- data/Release.md +0 -9
- data/gemfiles/2.1-Gemfile +0 -12
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -23
- data/lib/puma/daemon_ext.rb +0 -31
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/puma.gemspec +0 -20
data/lib/puma/cluster.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/runner'
|
2
4
|
require 'puma/util'
|
3
5
|
require 'puma/plugin'
|
@@ -5,9 +7,18 @@ require 'puma/plugin'
|
|
5
7
|
require 'time'
|
6
8
|
|
7
9
|
module Puma
|
10
|
+
# This class is instantiated by the `Puma::Launcher` and used
|
11
|
+
# to boot and serve a Ruby application when puma "workers" are needed
|
12
|
+
# i.e. when using multi-processes. For example `$ puma -w 5`
|
13
|
+
#
|
14
|
+
# At the core of this class is running an instance of `Puma::Server` which
|
15
|
+
# gets created via the `start_server` method from the `Puma::Runner` class
|
16
|
+
# that this inherits from.
|
17
|
+
#
|
18
|
+
# An instance of this class will spawn the number of processes passed in
|
19
|
+
# via the `spawn_workers` method call. Each worker will have it's own
|
20
|
+
# instance of a `Puma::Server`.
|
8
21
|
class Cluster < Runner
|
9
|
-
WORKER_CHECK_INTERVAL = 5
|
10
|
-
|
11
22
|
def initialize(cli, events)
|
12
23
|
super cli, events
|
13
24
|
|
@@ -24,7 +35,11 @@ module Puma
|
|
24
35
|
@workers.each { |x| x.term }
|
25
36
|
|
26
37
|
begin
|
27
|
-
|
38
|
+
loop do
|
39
|
+
wait_workers
|
40
|
+
break if @workers.empty?
|
41
|
+
sleep 0.2
|
42
|
+
end
|
28
43
|
rescue Interrupt
|
29
44
|
log "! Cancelled waiting for workers"
|
30
45
|
end
|
@@ -56,12 +71,13 @@ module Puma
|
|
56
71
|
@signal = "TERM"
|
57
72
|
@options = options
|
58
73
|
@first_term_sent = nil
|
74
|
+
@started_at = Time.now
|
59
75
|
@last_checkin = Time.now
|
60
76
|
@last_status = '{}'
|
61
|
-
@
|
77
|
+
@term = false
|
62
78
|
end
|
63
79
|
|
64
|
-
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status
|
80
|
+
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at
|
65
81
|
|
66
82
|
def booted?
|
67
83
|
@stage == :booted
|
@@ -72,12 +88,8 @@ module Puma
|
|
72
88
|
@stage = :booted
|
73
89
|
end
|
74
90
|
|
75
|
-
def
|
76
|
-
@
|
77
|
-
end
|
78
|
-
|
79
|
-
def dead!
|
80
|
-
@dead = true
|
91
|
+
def term?
|
92
|
+
@term
|
81
93
|
end
|
82
94
|
|
83
95
|
def ping!(status)
|
@@ -94,9 +106,9 @@ module Puma
|
|
94
106
|
if @first_term_sent && (Time.now - @first_term_sent) > @options[:worker_shutdown_timeout]
|
95
107
|
@signal = "KILL"
|
96
108
|
else
|
109
|
+
@term ||= true
|
97
110
|
@first_term_sent ||= Time.now
|
98
111
|
end
|
99
|
-
|
100
112
|
Process.kill @signal, @pid
|
101
113
|
rescue Errno::ESRCH
|
102
114
|
end
|
@@ -170,7 +182,7 @@ module Puma
|
|
170
182
|
def check_workers(force=false)
|
171
183
|
return if !force && @next_check && @next_check >= Time.now
|
172
184
|
|
173
|
-
@next_check = Time.now + WORKER_CHECK_INTERVAL
|
185
|
+
@next_check = Time.now + Const::WORKER_CHECK_INTERVAL
|
174
186
|
|
175
187
|
any = false
|
176
188
|
|
@@ -187,15 +199,7 @@ module Puma
|
|
187
199
|
# during this loop by giving the kernel time to kill them.
|
188
200
|
sleep 1 if any
|
189
201
|
|
190
|
-
|
191
|
-
pid = Process.waitpid(-1, Process::WNOHANG)
|
192
|
-
break unless pid
|
193
|
-
|
194
|
-
@workers.delete_if { |w| w.pid == pid }
|
195
|
-
end
|
196
|
-
|
197
|
-
@workers.delete_if(&:dead?)
|
198
|
-
|
202
|
+
wait_workers
|
199
203
|
cull_workers
|
200
204
|
spawn_workers
|
201
205
|
|
@@ -212,8 +216,10 @@ module Puma
|
|
212
216
|
log "- Stopping #{w.pid} for phased upgrade..."
|
213
217
|
end
|
214
218
|
|
215
|
-
w.term
|
216
|
-
|
219
|
+
unless w.term?
|
220
|
+
w.term
|
221
|
+
log "- #{w.signal} sent to #{w.pid}..."
|
222
|
+
end
|
217
223
|
end
|
218
224
|
end
|
219
225
|
end
|
@@ -224,12 +230,13 @@ module Puma
|
|
224
230
|
begin
|
225
231
|
@wakeup.write "!" unless @wakeup.closed?
|
226
232
|
rescue SystemCallError, IOError
|
233
|
+
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
227
234
|
end
|
228
235
|
end
|
229
236
|
|
230
237
|
def worker(index, master)
|
231
|
-
title
|
232
|
-
title
|
238
|
+
title = "puma: cluster worker #{index}: #{master}"
|
239
|
+
title += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
|
233
240
|
$0 = title
|
234
241
|
|
235
242
|
Signal.trap "SIGINT", "IGNORE"
|
@@ -239,6 +246,7 @@ module Puma
|
|
239
246
|
@suicide_pipe.close
|
240
247
|
|
241
248
|
Thread.new do
|
249
|
+
Puma.set_thread_name "worker check pipe"
|
242
250
|
IO.select [@check_pipe]
|
243
251
|
log "! Detected parent died, dying"
|
244
252
|
exit! 1
|
@@ -261,27 +269,33 @@ module Puma
|
|
261
269
|
server = start_server
|
262
270
|
|
263
271
|
Signal.trap "SIGTERM" do
|
272
|
+
@worker_write << "e#{Process.pid}\n" rescue nil
|
264
273
|
server.stop
|
265
274
|
end
|
266
275
|
|
267
276
|
begin
|
268
277
|
@worker_write << "b#{Process.pid}\n"
|
269
278
|
rescue SystemCallError, IOError
|
279
|
+
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
270
280
|
STDERR.puts "Master seems to have exited, exiting."
|
271
281
|
return
|
272
282
|
end
|
273
283
|
|
274
284
|
Thread.new(@worker_write) do |io|
|
285
|
+
Puma.set_thread_name "stat payload"
|
275
286
|
base_payload = "p#{Process.pid}"
|
276
287
|
|
277
288
|
while true
|
278
|
-
sleep WORKER_CHECK_INTERVAL
|
289
|
+
sleep Const::WORKER_CHECK_INTERVAL
|
279
290
|
begin
|
280
|
-
b = server.backlog
|
281
|
-
r = server.running
|
282
|
-
|
291
|
+
b = server.backlog || 0
|
292
|
+
r = server.running || 0
|
293
|
+
t = server.pool_capacity || 0
|
294
|
+
m = server.max_threads || 0
|
295
|
+
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m} }\n!
|
283
296
|
io << payload
|
284
297
|
rescue IOError
|
298
|
+
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
285
299
|
break
|
286
300
|
end
|
287
301
|
end
|
@@ -334,11 +348,13 @@ module Puma
|
|
334
348
|
Dir.chdir dir
|
335
349
|
end
|
336
350
|
|
351
|
+
# Inside of a child process, this will return all zeroes, as @workers is only populated in
|
352
|
+
# the master process.
|
337
353
|
def stats
|
338
354
|
old_worker_count = @workers.count { |w| w.phase != @phase }
|
339
355
|
booted_worker_count = @workers.count { |w| w.booted? }
|
340
|
-
worker_status = '[' + @workers.map{ |w| %Q!{ "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
|
341
|
-
%Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }!
|
356
|
+
worker_status = '[' + @workers.map { |w| %Q!{ "started_at": "#{w.started_at.utc.iso8601}", "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
|
357
|
+
%Q!{ "started_at": "#{@started_at.utc.iso8601}", "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }!
|
342
358
|
end
|
343
359
|
|
344
360
|
def preload?
|
@@ -372,7 +388,13 @@ module Puma
|
|
372
388
|
log "Early termination of worker"
|
373
389
|
exit! 0
|
374
390
|
else
|
391
|
+
@launcher.close_binder_listeners
|
392
|
+
|
393
|
+
stop_workers
|
375
394
|
stop
|
395
|
+
|
396
|
+
raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm]
|
397
|
+
exit 0 # Clean exit, workers were stopped
|
376
398
|
end
|
377
399
|
end
|
378
400
|
end
|
@@ -466,7 +488,7 @@ module Puma
|
|
466
488
|
|
467
489
|
force_check = false
|
468
490
|
|
469
|
-
res = IO.select([read], nil, nil, WORKER_CHECK_INTERVAL)
|
491
|
+
res = IO.select([read], nil, nil, Const::WORKER_CHECK_INTERVAL)
|
470
492
|
|
471
493
|
if res
|
472
494
|
req = read.read_nonblock(1)
|
@@ -482,8 +504,11 @@ module Puma
|
|
482
504
|
w.boot!
|
483
505
|
log "- Worker #{w.index} (pid: #{pid}) booted, phase: #{w.phase}"
|
484
506
|
force_check = true
|
507
|
+
when "e"
|
508
|
+
# external term, see worker method, Signal.trap "SIGTERM"
|
509
|
+
w.instance_variable_set :@term, true
|
485
510
|
when "t"
|
486
|
-
w.
|
511
|
+
w.term unless w.term?
|
487
512
|
force_check = true
|
488
513
|
when "p"
|
489
514
|
w.ping!(result.sub(/^\d+/,'').chomp)
|
@@ -506,5 +531,24 @@ module Puma
|
|
506
531
|
@wakeup.close
|
507
532
|
end
|
508
533
|
end
|
534
|
+
|
535
|
+
private
|
536
|
+
|
537
|
+
# loops thru @workers, removing workers that exited, and calling
|
538
|
+
# `#term` if needed
|
539
|
+
def wait_workers
|
540
|
+
@workers.reject! do |w|
|
541
|
+
begin
|
542
|
+
if Process.wait(w.pid, Process::WNOHANG)
|
543
|
+
true
|
544
|
+
else
|
545
|
+
w.term if w.term?
|
546
|
+
nil
|
547
|
+
end
|
548
|
+
rescue Errno::ECHILD
|
549
|
+
true # child is already terminated
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
509
553
|
end
|
510
554
|
end
|
data/lib/puma/commonlogger.rb
CHANGED
data/lib/puma/configuration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/rack/builder'
|
2
4
|
require 'puma/plugin'
|
3
5
|
require 'puma/const'
|
@@ -18,7 +20,7 @@ module Puma
|
|
18
20
|
# In this class any "user" specified options take precedence over any
|
19
21
|
# "file" specified options, take precedence over any "default" options.
|
20
22
|
#
|
21
|
-
# User input is
|
23
|
+
# User input is preferred over "defaults":
|
22
24
|
# user_options = { foo: "bar" }
|
23
25
|
# default_options = { foo: "zoo" }
|
24
26
|
# options = UserFileDefaultOptions.new(user_options, default_options)
|
@@ -30,7 +32,7 @@ module Puma
|
|
30
32
|
# puts options.all_of(:foo)
|
31
33
|
# # => ["bar", "zoo"]
|
32
34
|
#
|
33
|
-
# A "file" option can be set. This config will be
|
35
|
+
# A "file" option can be set. This config will be preferred over "default" options
|
34
36
|
# but will defer to any available "user" specified options.
|
35
37
|
#
|
36
38
|
# user_options = { foo: "bar" }
|
@@ -180,30 +182,32 @@ module Puma
|
|
180
182
|
:worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
|
181
183
|
:remote_address => :socket,
|
182
184
|
:tag => method(:infer_tag),
|
183
|
-
:environment => ->{ ENV['RACK_ENV'] || "development" },
|
185
|
+
:environment => -> { ENV['RACK_ENV'] || "development" },
|
184
186
|
:rackup => DefaultRackup,
|
185
187
|
:logger => STDOUT,
|
186
|
-
:persistent_timeout => Const::PERSISTENT_TIMEOUT
|
188
|
+
:persistent_timeout => Const::PERSISTENT_TIMEOUT,
|
189
|
+
:first_data_timeout => Const::FIRST_DATA_TIMEOUT,
|
190
|
+
:raise_exception_on_sigterm => true
|
187
191
|
}
|
188
192
|
end
|
189
193
|
|
190
194
|
def load
|
195
|
+
config_files.each { |config_file| @file_dsl._load_from(config_file) }
|
196
|
+
|
197
|
+
@options
|
198
|
+
end
|
199
|
+
|
200
|
+
def config_files
|
191
201
|
files = @options.all_of(:config_files)
|
192
202
|
|
193
|
-
if files
|
194
|
-
|
195
|
-
File.exist?(f)
|
196
|
-
}
|
203
|
+
return [] if files == ['-']
|
204
|
+
return files if files.any?
|
197
205
|
|
198
|
-
|
199
|
-
|
200
|
-
files = []
|
206
|
+
first_default_file = %W(config/puma/#{environment_str}.rb config/puma.rb).find do |f|
|
207
|
+
File.exist?(f)
|
201
208
|
end
|
202
209
|
|
203
|
-
|
204
|
-
@file_dsl._load_from(f)
|
205
|
-
end
|
206
|
-
@options
|
210
|
+
[first_default_file]
|
207
211
|
end
|
208
212
|
|
209
213
|
# Call once all configuration (included from rackup files)
|
@@ -263,6 +267,10 @@ module Puma
|
|
263
267
|
@options[:environment]
|
264
268
|
end
|
265
269
|
|
270
|
+
def environment_str
|
271
|
+
environment.respond_to?(:call) ? environment.call : environment
|
272
|
+
end
|
273
|
+
|
266
274
|
def load_plugin(name)
|
267
275
|
@plugins.create name
|
268
276
|
end
|
@@ -340,7 +348,7 @@ module Puma
|
|
340
348
|
end
|
341
349
|
|
342
350
|
if bytes
|
343
|
-
token = ""
|
351
|
+
token = "".dup
|
344
352
|
bytes.each_byte { |b| token << b.to_s(16) }
|
345
353
|
else
|
346
354
|
token = (0..count).to_a.map { rand(255).to_s(16) }.join
|
data/lib/puma/const.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
module Puma
|
3
5
|
class UnsupportedOption < RuntimeError
|
4
6
|
end
|
@@ -53,6 +55,8 @@ module Puma
|
|
53
55
|
415 => 'Unsupported Media Type',
|
54
56
|
416 => 'Range Not Satisfiable',
|
55
57
|
417 => 'Expectation Failed',
|
58
|
+
418 => 'I\'m A Teapot',
|
59
|
+
421 => 'Misdirected Request',
|
56
60
|
422 => 'Unprocessable Entity',
|
57
61
|
423 => 'Locked',
|
58
62
|
424 => 'Failed Dependency',
|
@@ -60,6 +64,7 @@ module Puma
|
|
60
64
|
428 => 'Precondition Required',
|
61
65
|
429 => 'Too Many Requests',
|
62
66
|
431 => 'Request Header Fields Too Large',
|
67
|
+
451 => 'Unavailable For Legal Reasons',
|
63
68
|
500 => 'Internal Server Error',
|
64
69
|
501 => 'Not Implemented',
|
65
70
|
502 => 'Bad Gateway',
|
@@ -95,8 +100,8 @@ module Puma
|
|
95
100
|
# too taxing on performance.
|
96
101
|
module Const
|
97
102
|
|
98
|
-
PUMA_VERSION = VERSION = "3.
|
99
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "4.3.1".freeze
|
104
|
+
CODE_NAME = "Mysterious Traveller".freeze
|
100
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
101
106
|
|
102
107
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
@@ -113,31 +118,35 @@ module Puma
|
|
113
118
|
# sending data back
|
114
119
|
WRITE_TIMEOUT = 10
|
115
120
|
|
121
|
+
# How many requests to attempt inline before sending a client back to
|
122
|
+
# the reactor to be subject to normal ordering. The idea here is that
|
123
|
+
# we amortize the cost of going back to the reactor for a well behaved
|
124
|
+
# but very "greedy" client across 10 requests. This prevents a not
|
125
|
+
# well behaved client from monopolizing the thread forever.
|
126
|
+
MAX_FAST_INLINE = 10
|
127
|
+
|
116
128
|
# The original URI requested by the client.
|
117
129
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
118
130
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
119
131
|
QUERY_STRING = 'QUERY_STRING'.freeze
|
132
|
+
CONTENT_LENGTH = "CONTENT_LENGTH".freeze
|
120
133
|
|
121
134
|
PATH_INFO = 'PATH_INFO'.freeze
|
122
135
|
|
123
136
|
PUMA_TMP_BASE = "puma".freeze
|
124
137
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze
|
138
|
-
|
139
|
-
# A common header for indicating the server is too busy. Not used yet.
|
140
|
-
ERROR_503_RESPONSE = "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
138
|
+
ERROR_RESPONSE = {
|
139
|
+
# Indicate that we couldn't parse the request
|
140
|
+
400 => "HTTP/1.1 400 Bad Request\r\n\r\n".freeze,
|
141
|
+
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
142
|
+
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\nNOT FOUND".freeze,
|
143
|
+
# The standard empty 408 response for requests that timed out.
|
144
|
+
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\n".freeze,
|
145
|
+
# Indicate that there was an internal error, obviously.
|
146
|
+
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze,
|
147
|
+
# A common header for indicating the server is too busy. Not used yet.
|
148
|
+
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
149
|
+
}
|
141
150
|
|
142
151
|
# The basic max request size we'll try to read.
|
143
152
|
CHUNK_SIZE = 16 * 1024
|
@@ -155,6 +164,9 @@ module Puma
|
|
155
164
|
LINE_END = "\r\n".freeze
|
156
165
|
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
157
166
|
HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR".freeze
|
167
|
+
HTTP_X_FORWARDED_SSL = "HTTP_X_FORWARDED_SSL".freeze
|
168
|
+
HTTP_X_FORWARDED_SCHEME = "HTTP_X_FORWARDED_SCHEME".freeze
|
169
|
+
HTTP_X_FORWARDED_PROTO = "HTTP_X_FORWARDED_PROTO".freeze
|
158
170
|
|
159
171
|
SERVER_NAME = "SERVER_NAME".freeze
|
160
172
|
SERVER_PORT = "SERVER_PORT".freeze
|
@@ -220,5 +232,11 @@ module Puma
|
|
220
232
|
HIJACK_P = "rack.hijack?".freeze
|
221
233
|
HIJACK = "rack.hijack".freeze
|
222
234
|
HIJACK_IO = "rack.hijack_io".freeze
|
235
|
+
|
236
|
+
EARLY_HINTS = "rack.early_hints".freeze
|
237
|
+
|
238
|
+
# Mininum interval to checks worker health
|
239
|
+
WORKER_CHECK_INTERVAL = 5
|
240
|
+
|
223
241
|
end
|
224
242
|
end
|