puma 5.6.4 → 6.4.2
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 +372 -6
- data/LICENSE +0 -0
- data/README.md +79 -29
- 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 +12 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +3 -6
- 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 +22 -10
- 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 +153 -27
- 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 +167 -65
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +7 -4
- data/lib/puma/binder.rb +51 -54
- data/lib/puma/cli.rb +16 -18
- data/lib/puma/client.rb +100 -26
- data/lib/puma/cluster/worker.rb +18 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +102 -40
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +77 -59
- data/lib/puma/const.rb +129 -92
- data/lib/puma/control_cli.rb +33 -23
- data/lib/puma/detect.rb +7 -4
- data/lib/puma/dsl.rb +251 -53
- data/lib/puma/error_logger.rb +18 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -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 +113 -175
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +26 -12
- data/lib/puma/minissl.rb +113 -15
- data/lib/puma/null_io.rb +21 -2
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +6 -6
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/rack_default.rb +19 -4
- data/lib/puma/reactor.rb +19 -10
- data/lib/puma/request.rb +365 -166
- data/lib/puma/runner.rb +56 -20
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +137 -87
- data/lib/puma/single.rb +13 -11
- data/lib/puma/state_file.rb +4 -6
- data/lib/puma/thread_pool.rb +57 -19
- data/lib/puma/util.rb +12 -14
- data/lib/puma.rb +12 -11
- data/lib/rack/handler/puma.rb +113 -86
- data/tools/Dockerfile +2 -2
- data/tools/trickletest.rb +0 -0
- metadata +11 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/puma/systemd.rb +0 -46
data/lib/puma/dsl.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'const'
|
4
|
+
require_relative 'util'
|
4
5
|
|
5
6
|
module Puma
|
6
7
|
# The methods that are available for use inside the configuration file.
|
@@ -31,8 +32,24 @@ module Puma
|
|
31
32
|
# You can also find many examples being used by the test suite in
|
32
33
|
# +test/config+.
|
33
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
|
+
#
|
34
51
|
class DSL
|
35
|
-
|
52
|
+
ON_WORKER_KEY = [String, Symbol].freeze
|
36
53
|
|
37
54
|
# convenience method so logic can be used in CI
|
38
55
|
# @see ssl_bind
|
@@ -46,27 +63,60 @@ module Puma
|
|
46
63
|
else ''
|
47
64
|
end
|
48
65
|
|
49
|
-
ca_additions = "&ca=#{opts[:ca]}" if ['peer', 'force_peer'].include?(verify)
|
66
|
+
ca_additions = "&ca=#{Puma::Util.escape(opts[:ca])}" if ['peer', 'force_peer'].include?(verify)
|
50
67
|
|
68
|
+
low_latency_str = opts.key?(:low_latency) ? "&low_latency=#{opts[:low_latency]}" : ''
|
51
69
|
backlog_str = opts[:backlog] ? "&backlog=#{Integer(opts[:backlog])}" : ''
|
52
70
|
|
53
71
|
if defined?(JRUBY_VERSION)
|
54
|
-
|
55
|
-
|
72
|
+
cipher_suites = opts[:ssl_cipher_list] ? "&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil # old name
|
73
|
+
cipher_suites = "#{cipher_suites}&cipher_suites=#{opts[:cipher_suites]}" if opts[:cipher_suites]
|
74
|
+
protocols = opts[:protocols] ? "&protocols=#{opts[:protocols]}" : nil
|
56
75
|
|
57
76
|
keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
|
77
|
+
keystore_additions = "#{keystore_additions}&keystore-type=#{opts[:keystore_type]}" if opts[:keystore_type]
|
78
|
+
if opts[:truststore]
|
79
|
+
truststore_additions = "&truststore=#{opts[:truststore]}"
|
80
|
+
truststore_additions = "#{truststore_additions}&truststore-pass=#{opts[:truststore_pass]}" if opts[:truststore_pass]
|
81
|
+
truststore_additions = "#{truststore_additions}&truststore-type=#{opts[:truststore_type]}" if opts[:truststore_type]
|
82
|
+
end
|
58
83
|
|
59
|
-
"ssl://#{host}:#{port}?#{keystore_additions}#{
|
84
|
+
"ssl://#{host}:#{port}?#{keystore_additions}#{truststore_additions}#{cipher_suites}#{protocols}" \
|
60
85
|
"&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}"
|
61
86
|
else
|
62
|
-
ssl_cipher_filter = opts[:ssl_cipher_filter] ?
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
87
|
+
ssl_cipher_filter = opts[:ssl_cipher_filter] ? "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
|
88
|
+
v_flags = (ary = opts[:verification_flags]) ? "&verification_flags=#{Array(ary).join ','}" : nil
|
89
|
+
|
90
|
+
cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil
|
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
|
93
|
+
|
94
|
+
reuse_flag =
|
95
|
+
if (reuse = opts[:reuse])
|
96
|
+
if reuse == true
|
97
|
+
'&reuse=dflt'
|
98
|
+
elsif reuse.is_a?(Hash) && (reuse.key?(:size) || reuse.key?(:timeout))
|
99
|
+
val = +''
|
100
|
+
if (size = reuse[:size]) && Integer === size
|
101
|
+
val << size.to_s
|
102
|
+
end
|
103
|
+
if (timeout = reuse[:timeout]) && Integer === timeout
|
104
|
+
val << ",#{timeout}"
|
105
|
+
end
|
106
|
+
if val.empty?
|
107
|
+
nil
|
108
|
+
else
|
109
|
+
"&reuse=#{val}"
|
110
|
+
end
|
111
|
+
else
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
else
|
115
|
+
nil
|
116
|
+
end
|
67
117
|
|
68
|
-
"ssl://#{host}:#{port}
|
69
|
-
"#{
|
118
|
+
"ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}" \
|
119
|
+
"#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}#{low_latency_str}"
|
70
120
|
end
|
71
121
|
end
|
72
122
|
|
@@ -102,7 +152,7 @@ module Puma
|
|
102
152
|
end
|
103
153
|
|
104
154
|
def default_host
|
105
|
-
@options[:default_host] || Configuration::
|
155
|
+
@options[:default_host] || Configuration::DEFAULTS[:tcp_host]
|
106
156
|
end
|
107
157
|
|
108
158
|
def inject(&blk)
|
@@ -202,6 +252,7 @@ module Puma
|
|
202
252
|
#
|
203
253
|
# * Set the socket backlog depth with +backlog+, default is 1024.
|
204
254
|
# * Set up an SSL certificate with +key+ & +cert+.
|
255
|
+
# * Set up an SSL certificate for mTLS with +key+, +cert+, +ca+ and +verify_mode+.
|
205
256
|
# * Set whether to optimize for low latency instead of throughput with
|
206
257
|
# +low_latency+, default is to not optimize for low latency. This is done
|
207
258
|
# via +Socket::TCP_NODELAY+.
|
@@ -211,6 +262,8 @@ module Puma
|
|
211
262
|
# bind 'unix:///var/run/puma.sock?backlog=512'
|
212
263
|
# @example SSL cert
|
213
264
|
# bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem'
|
265
|
+
# @example SSL cert for mutual TLS (mTLS)
|
266
|
+
# bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem&ca=ca.pem&verify_mode=force_peer'
|
214
267
|
# @example Disable optimization for low latency
|
215
268
|
# bind 'tcp://0.0.0.0:9292?low_latency=false'
|
216
269
|
# @example Socket permissions
|
@@ -262,16 +315,22 @@ module Puma
|
|
262
315
|
bind URI::Generic.build(scheme: 'tcp', host: host, port: Integer(port)).to_s
|
263
316
|
end
|
264
317
|
|
318
|
+
# Define how long the tcp socket stays open, if no data has been received.
|
319
|
+
# @see Puma::Server.new
|
320
|
+
def first_data_timeout(seconds)
|
321
|
+
@options[:first_data_timeout] = Integer(seconds)
|
322
|
+
end
|
323
|
+
|
265
324
|
# Define how long persistent connections can be idle before Puma closes them.
|
266
325
|
# @see Puma::Server.new
|
267
326
|
def persistent_timeout(seconds)
|
268
327
|
@options[:persistent_timeout] = Integer(seconds)
|
269
328
|
end
|
270
329
|
|
271
|
-
#
|
330
|
+
# If a new request is not received within this number of seconds, begin shutting down.
|
272
331
|
# @see Puma::Server.new
|
273
|
-
def
|
274
|
-
@options[:
|
332
|
+
def idle_timeout(seconds)
|
333
|
+
@options[:idle_timeout] = Integer(seconds)
|
275
334
|
end
|
276
335
|
|
277
336
|
# Work around leaky apps that leave garbage in Thread locals
|
@@ -367,6 +426,11 @@ module Puma
|
|
367
426
|
@options[:log_requests] = which
|
368
427
|
end
|
369
428
|
|
429
|
+
# Pass in a custom logging class instance
|
430
|
+
def custom_logger(custom_logger)
|
431
|
+
@options[:custom_logger] = custom_logger
|
432
|
+
end
|
433
|
+
|
370
434
|
# Show debugging info
|
371
435
|
#
|
372
436
|
def debug
|
@@ -448,6 +512,16 @@ module Puma
|
|
448
512
|
# Puma will assume you are using the +localhost+ gem and try to load the
|
449
513
|
# appropriate files.
|
450
514
|
#
|
515
|
+
# When using the options hash parameter, the `reuse:` value is either
|
516
|
+
# `true`, which sets reuse 'on' with default values, or a hash, with `:size`
|
517
|
+
# and/or `:timeout` keys, each with integer values.
|
518
|
+
#
|
519
|
+
# The `cert:` options hash parameter can be the path to a certificate
|
520
|
+
# file including all intermediate certificates in PEM format.
|
521
|
+
#
|
522
|
+
# The `cert_pem:` options hash parameter can be String containing the
|
523
|
+
# cerificate and all intermediate certificates in PEM format.
|
524
|
+
#
|
451
525
|
# @example
|
452
526
|
# ssl_bind '127.0.0.1', '9292', {
|
453
527
|
# cert: path_to_cert,
|
@@ -455,6 +529,7 @@ module Puma
|
|
455
529
|
# ssl_cipher_filter: cipher_filter, # optional
|
456
530
|
# verify_mode: verify_mode, # default 'none'
|
457
531
|
# verification_flags: flags, # optional, not supported by JRuby
|
532
|
+
# reuse: true # optional
|
458
533
|
# }
|
459
534
|
#
|
460
535
|
# @example Using self-signed certificate with the +localhost+ gem:
|
@@ -464,6 +539,7 @@ module Puma
|
|
464
539
|
# ssl_bind '127.0.0.1', '9292', {
|
465
540
|
# cert_pem: File.read(path_to_cert),
|
466
541
|
# key_pem: File.read(path_to_key),
|
542
|
+
# reuse: {size: 2_000, timeout: 20} # optional
|
467
543
|
# }
|
468
544
|
#
|
469
545
|
# @example For JRuby, two keys are required: +keystore+ & +keystore_pass+
|
@@ -527,6 +603,11 @@ module Puma
|
|
527
603
|
@options[:silence_single_worker_warning] = true
|
528
604
|
end
|
529
605
|
|
606
|
+
# Disable warning message when running single mode with callback hook defined.
|
607
|
+
def silence_fork_callback_warning
|
608
|
+
@options[:silence_fork_callback_warning] = true
|
609
|
+
end
|
610
|
+
|
530
611
|
# Code to run immediately before master process
|
531
612
|
# forks workers (once on boot). These hooks can block if necessary
|
532
613
|
# to wait for background operations unknown to Puma to finish before
|
@@ -542,6 +623,8 @@ module Puma
|
|
542
623
|
# puts "Starting workers..."
|
543
624
|
# end
|
544
625
|
def before_fork(&block)
|
626
|
+
warn_if_in_single_mode('before_fork')
|
627
|
+
|
545
628
|
@options[:before_fork] ||= []
|
546
629
|
@options[:before_fork] << block
|
547
630
|
end
|
@@ -556,9 +639,10 @@ module Puma
|
|
556
639
|
# on_worker_boot do
|
557
640
|
# puts 'Before worker boot...'
|
558
641
|
# end
|
559
|
-
def on_worker_boot(&block)
|
560
|
-
|
561
|
-
|
642
|
+
def on_worker_boot(key = nil, &block)
|
643
|
+
warn_if_in_single_mode('on_worker_boot')
|
644
|
+
|
645
|
+
process_hook :before_worker_boot, key, block, 'on_worker_boot'
|
562
646
|
end
|
563
647
|
|
564
648
|
# Code to run immediately before a worker shuts
|
@@ -573,9 +657,10 @@ module Puma
|
|
573
657
|
# on_worker_shutdown do
|
574
658
|
# puts 'On worker shutdown...'
|
575
659
|
# end
|
576
|
-
def on_worker_shutdown(&block)
|
577
|
-
|
578
|
-
|
660
|
+
def on_worker_shutdown(key = nil, &block)
|
661
|
+
warn_if_in_single_mode('on_worker_shutdown')
|
662
|
+
|
663
|
+
process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
|
579
664
|
end
|
580
665
|
|
581
666
|
# Code to run in the master right before a worker is started. The worker's
|
@@ -589,8 +674,9 @@ module Puma
|
|
589
674
|
# puts 'Before worker fork...'
|
590
675
|
# end
|
591
676
|
def on_worker_fork(&block)
|
592
|
-
|
593
|
-
|
677
|
+
warn_if_in_single_mode('on_worker_fork')
|
678
|
+
|
679
|
+
process_hook :before_worker_fork, nil, block, 'on_worker_fork'
|
594
680
|
end
|
595
681
|
|
596
682
|
# Code to run in the master after a worker has been started. The worker's
|
@@ -604,12 +690,23 @@ module Puma
|
|
604
690
|
# puts 'After worker fork...'
|
605
691
|
# end
|
606
692
|
def after_worker_fork(&block)
|
607
|
-
|
608
|
-
|
693
|
+
warn_if_in_single_mode('after_worker_fork')
|
694
|
+
|
695
|
+
process_hook :after_worker_fork, nil, block, 'after_worker_fork'
|
609
696
|
end
|
610
697
|
|
611
698
|
alias_method :after_worker_boot, :after_worker_fork
|
612
699
|
|
700
|
+
# Code to run after puma is booted (works for both: single and clustered)
|
701
|
+
#
|
702
|
+
# @example
|
703
|
+
# on_booted do
|
704
|
+
# puts 'After booting...'
|
705
|
+
# end
|
706
|
+
def on_booted(&block)
|
707
|
+
@config.options[:events].on_booted(&block)
|
708
|
+
end
|
709
|
+
|
613
710
|
# When `fork_worker` is enabled, code to run in Worker 0
|
614
711
|
# before all other workers are re-forked from this process,
|
615
712
|
# after the server has temporarily stopped serving requests
|
@@ -628,9 +725,53 @@ module Puma
|
|
628
725
|
# end
|
629
726
|
# @version 5.0.0
|
630
727
|
#
|
631
|
-
def on_refork(&block)
|
632
|
-
|
633
|
-
|
728
|
+
def on_refork(key = nil, &block)
|
729
|
+
process_hook :before_refork, key, block, 'on_refork'
|
730
|
+
end
|
731
|
+
|
732
|
+
# Provide a block to be executed just before a thread is added to the thread
|
733
|
+
# pool. Be careful: while the block executes, thread creation is delayed, and
|
734
|
+
# probably a request will have to wait too! The new thread will not be added to
|
735
|
+
# the threadpool until the provided block returns.
|
736
|
+
#
|
737
|
+
# Return values are ignored.
|
738
|
+
# Raising an exception will log a warning.
|
739
|
+
#
|
740
|
+
# This hook is useful for doing something when the thread pool grows.
|
741
|
+
#
|
742
|
+
# This can be called multiple times to add several hooks.
|
743
|
+
#
|
744
|
+
# @example
|
745
|
+
# on_thread_start do
|
746
|
+
# puts 'On thread start...'
|
747
|
+
# end
|
748
|
+
def on_thread_start(&block)
|
749
|
+
@options[:before_thread_start] ||= []
|
750
|
+
@options[:before_thread_start] << block
|
751
|
+
end
|
752
|
+
|
753
|
+
# Provide a block to be executed after a thread is trimmed from the thread
|
754
|
+
# pool. Be careful: while this block executes, Puma's main loop is
|
755
|
+
# blocked, so no new requests will be picked up.
|
756
|
+
#
|
757
|
+
# This hook only runs when a thread in the threadpool is trimmed by Puma.
|
758
|
+
# It does not run when a thread dies due to exceptions or any other cause.
|
759
|
+
#
|
760
|
+
# Return values are ignored.
|
761
|
+
# Raising an exception will log a warning.
|
762
|
+
#
|
763
|
+
# This hook is useful for cleaning up thread local resources when a thread
|
764
|
+
# is trimmed.
|
765
|
+
#
|
766
|
+
# This can be called multiple times to add several hooks.
|
767
|
+
#
|
768
|
+
# @example
|
769
|
+
# on_thread_exit do
|
770
|
+
# puts 'On thread exit...'
|
771
|
+
# end
|
772
|
+
def on_thread_exit(&block)
|
773
|
+
@options[:before_thread_exit] ||= []
|
774
|
+
@options[:before_thread_exit] << block
|
634
775
|
end
|
635
776
|
|
636
777
|
# Code to run out-of-band when the worker is idle.
|
@@ -643,8 +784,7 @@ module Puma
|
|
643
784
|
#
|
644
785
|
# This can be called multiple times to add several hooks.
|
645
786
|
def out_of_band(&block)
|
646
|
-
|
647
|
-
@options[:out_of_band] << block
|
787
|
+
process_hook :out_of_band, nil, block, 'out_of_band'
|
648
788
|
end
|
649
789
|
|
650
790
|
# The directory to operate out of.
|
@@ -765,7 +905,8 @@ module Puma
|
|
765
905
|
# not a request timeout, it is to protect against a hung or dead process.
|
766
906
|
# Setting this value will not protect against slow requests.
|
767
907
|
#
|
768
|
-
#
|
908
|
+
# This value must be greater than worker_check_interval.
|
909
|
+
# The default value is 60 seconds.
|
769
910
|
#
|
770
911
|
# @note Cluster mode only.
|
771
912
|
# @example
|
@@ -774,7 +915,7 @@ module Puma
|
|
774
915
|
#
|
775
916
|
def worker_timeout(timeout)
|
776
917
|
timeout = Integer(timeout)
|
777
|
-
min = @options.fetch(:worker_check_interval,
|
918
|
+
min = @options.fetch(:worker_check_interval, Configuration::DEFAULTS[:worker_check_interval])
|
778
919
|
|
779
920
|
if timeout <= min
|
780
921
|
raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})"
|
@@ -878,13 +1019,16 @@ module Puma
|
|
878
1019
|
# There are 5 possible values:
|
879
1020
|
#
|
880
1021
|
# 1. **:socket** (the default) - read the peername from the socket using the
|
881
|
-
# syscall. This is the normal behavior.
|
1022
|
+
# syscall. This is the normal behavior. If this fails for any reason (e.g.,
|
1023
|
+
# if the peer disconnects between the connection being accepted and the getpeername
|
1024
|
+
# system call), Puma will return "0.0.0.0"
|
882
1025
|
# 2. **:localhost** - set the remote address to "127.0.0.1"
|
883
1026
|
# 3. **header: <http_header>**- set the remote address to the value of the
|
884
1027
|
# provided http header. For instance:
|
885
1028
|
# `set_remote_address header: "X-Real-IP"`.
|
886
1029
|
# Only the first word (as separated by spaces or comma) is used, allowing
|
887
|
-
# headers such as X-Forwarded-For to be used as well.
|
1030
|
+
# headers such as X-Forwarded-For to be used as well. If this header is absent,
|
1031
|
+
# Puma will fall back to the behavior of :socket
|
888
1032
|
# 4. **proxy_protocol: :v1**- set the remote address to the value read from the
|
889
1033
|
# HAproxy PROXY protocol, version 1. If the request does not have the PROXY
|
890
1034
|
# protocol attached to it, will fall back to :socket
|
@@ -938,23 +1082,6 @@ module Puma
|
|
938
1082
|
@options[:fork_worker] = Integer(after_requests)
|
939
1083
|
end
|
940
1084
|
|
941
|
-
# When enabled, Puma will GC 4 times before forking workers.
|
942
|
-
# If available (Ruby 2.7+), we will also call GC.compact.
|
943
|
-
# Not recommended for non-MRI Rubies.
|
944
|
-
#
|
945
|
-
# Based on the work of Koichi Sasada and Aaron Patterson, this option may
|
946
|
-
# decrease memory utilization of preload-enabled cluster-mode Pumas. It will
|
947
|
-
# also increase time to boot and fork. See your logs for details on how much
|
948
|
-
# time this adds to your boot process. For most apps, it will be less than one
|
949
|
-
# second.
|
950
|
-
#
|
951
|
-
# @see Puma::Cluster#nakayoshi_gc
|
952
|
-
# @version 5.0.0
|
953
|
-
#
|
954
|
-
def nakayoshi_fork(enabled=true)
|
955
|
-
@options[:nakayoshi_fork] = enabled
|
956
|
-
end
|
957
|
-
|
958
1085
|
# The number of requests to attempt inline before sending a client back to
|
959
1086
|
# the reactor to be subject to normal ordering.
|
960
1087
|
#
|
@@ -985,6 +1112,51 @@ module Puma
|
|
985
1112
|
@options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled
|
986
1113
|
end
|
987
1114
|
|
1115
|
+
# Specify how big the request payload should be, in bytes.
|
1116
|
+
# This limit is compared against Content-Length HTTP header.
|
1117
|
+
# If the payload size (CONTENT_LENGTH) is larger than http_content_length_limit,
|
1118
|
+
# HTTP 413 status code is returned.
|
1119
|
+
#
|
1120
|
+
# When no Content-Length http header is present, it is compared against the
|
1121
|
+
# size of the body of the request.
|
1122
|
+
#
|
1123
|
+
# The default value for http_content_length_limit is nil.
|
1124
|
+
def http_content_length_limit(limit)
|
1125
|
+
@options[:http_content_length_limit] = limit
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
# Supported http methods, which will replace `Puma::Const::SUPPORTED_HTTP_METHODS`.
|
1129
|
+
# The value of `:any` will allows all methods, otherwise, the value must be
|
1130
|
+
# an array of strings. Note that methods are all uppercase.
|
1131
|
+
#
|
1132
|
+
# `Puma::Const::SUPPORTED_HTTP_METHODS` is conservative, if you want a
|
1133
|
+
# complete set of methods, the methods defined by the
|
1134
|
+
# [IANA Method Registry](https://www.iana.org/assignments/http-methods/http-methods.xhtml)
|
1135
|
+
# are pre-defined as the constant `Puma::Const::IANA_HTTP_METHODS`.
|
1136
|
+
#
|
1137
|
+
# @note If the `methods` value is `:any`, no method check with be performed,
|
1138
|
+
# similar to Puma v5 and earlier.
|
1139
|
+
#
|
1140
|
+
# @example Adds 'PROPFIND' to existing supported methods
|
1141
|
+
# supported_http_methods(Puma::Const::SUPPORTED_HTTP_METHODS + ['PROPFIND'])
|
1142
|
+
# @example Restricts methods to the array elements
|
1143
|
+
# supported_http_methods %w[HEAD GET POST PUT DELETE OPTIONS PROPFIND]
|
1144
|
+
# @example Restricts methods to the methods in the IANA Registry
|
1145
|
+
# supported_http_methods Puma::Const::IANA_HTTP_METHODS
|
1146
|
+
# @example Allows any method
|
1147
|
+
# supported_http_methods :any
|
1148
|
+
#
|
1149
|
+
def supported_http_methods(methods)
|
1150
|
+
if methods == :any
|
1151
|
+
@options[:supported_http_methods] = :any
|
1152
|
+
elsif Array === methods && methods == (ary = methods.grep(String).uniq) &&
|
1153
|
+
!ary.empty?
|
1154
|
+
@options[:supported_http_methods] = ary
|
1155
|
+
else
|
1156
|
+
raise "supported_http_methods must be ':any' or a unique array of strings"
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
|
988
1160
|
private
|
989
1161
|
|
990
1162
|
# To avoid adding cert_pem and key_pem as URI params, we store them on the
|
@@ -1004,5 +1176,31 @@ module Puma
|
|
1004
1176
|
end
|
1005
1177
|
end
|
1006
1178
|
end
|
1179
|
+
|
1180
|
+
def process_hook(options_key, key, block, meth)
|
1181
|
+
@options[options_key] ||= []
|
1182
|
+
if ON_WORKER_KEY.include? key.class
|
1183
|
+
@options[options_key] << [block, key.to_sym]
|
1184
|
+
elsif key.nil?
|
1185
|
+
@options[options_key] << block
|
1186
|
+
else
|
1187
|
+
raise "'#{meth}' key must be String or Symbol"
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
def warn_if_in_single_mode(hook_name)
|
1192
|
+
return if @options[:silence_fork_callback_warning]
|
1193
|
+
# user_options (CLI) have precedence over config file
|
1194
|
+
workers_val = @config.options.user_options[:workers] || @options[:workers] ||
|
1195
|
+
@config.puma_default_options[:workers] || 0
|
1196
|
+
if workers_val == 0
|
1197
|
+
log_string =
|
1198
|
+
"Warning: You specified code to run in a `#{hook_name}` block, " \
|
1199
|
+
"but Puma is not configured to run in cluster mode (worker count > 0 ), " \
|
1200
|
+
"so your `#{hook_name}` block did not run"
|
1201
|
+
|
1202
|
+
LogWriter.stdio.log(log_string)
|
1203
|
+
end
|
1204
|
+
end
|
1007
1205
|
end
|
1008
1206
|
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,19 @@ 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, Errno::EINVAL
|
106
|
+
# 'Invalid argument' (Errno::EINVAL) may be raised by flush
|
107
|
+
end
|
108
|
+
end
|
109
|
+
rescue ThreadError
|
102
110
|
end
|
111
|
+
private :internal_write
|
103
112
|
end
|
104
113
|
end
|