puma 5.6.9-java → 6.6.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +465 -18
  3. data/README.md +152 -42
  4. data/bin/puma-wild +1 -1
  5. data/docs/compile_options.md +34 -0
  6. data/docs/fork_worker.md +12 -4
  7. data/docs/java_options.md +54 -0
  8. data/docs/kubernetes.md +12 -0
  9. data/docs/nginx.md +1 -1
  10. data/docs/plugins.md +4 -0
  11. data/docs/restart.md +1 -0
  12. data/docs/signals.md +2 -2
  13. data/docs/stats.md +8 -3
  14. data/docs/systemd.md +13 -7
  15. data/docs/testing_benchmarks_local_files.md +150 -0
  16. data/docs/testing_test_rackup_ci_files.md +36 -0
  17. data/ext/puma_http11/extconf.rb +27 -17
  18. data/ext/puma_http11/http11_parser.c +1 -1
  19. data/ext/puma_http11/http11_parser.h +1 -1
  20. data/ext/puma_http11/http11_parser.java.rl +2 -2
  21. data/ext/puma_http11/http11_parser.rl +2 -2
  22. data/ext/puma_http11/http11_parser_common.rl +2 -2
  23. data/ext/puma_http11/mini_ssl.c +137 -19
  24. data/ext/puma_http11/org/jruby/puma/Http11.java +31 -10
  25. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  26. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +157 -53
  27. data/ext/puma_http11/puma_http11.c +21 -10
  28. data/lib/puma/app/status.rb +4 -4
  29. data/lib/puma/binder.rb +60 -55
  30. data/lib/puma/cli.rb +22 -20
  31. data/lib/puma/client.rb +93 -30
  32. data/lib/puma/cluster/worker.rb +27 -17
  33. data/lib/puma/cluster/worker_handle.rb +8 -6
  34. data/lib/puma/cluster.rb +121 -47
  35. data/lib/puma/commonlogger.rb +21 -14
  36. data/lib/puma/configuration.rb +101 -65
  37. data/lib/puma/const.rb +141 -93
  38. data/lib/puma/control_cli.rb +19 -15
  39. data/lib/puma/detect.rb +7 -4
  40. data/lib/puma/dsl.rb +521 -88
  41. data/lib/puma/error_logger.rb +22 -13
  42. data/lib/puma/events.rb +6 -126
  43. data/lib/puma/io_buffer.rb +39 -4
  44. data/lib/puma/jruby_restart.rb +0 -15
  45. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  46. data/lib/puma/launcher.rb +121 -181
  47. data/lib/puma/log_writer.rb +147 -0
  48. data/lib/puma/minissl/context_builder.rb +27 -12
  49. data/lib/puma/minissl.rb +105 -11
  50. data/lib/puma/null_io.rb +42 -2
  51. data/lib/puma/plugin/systemd.rb +90 -0
  52. data/lib/puma/plugin/tmp_restart.rb +1 -1
  53. data/lib/puma/puma_http11.jar +0 -0
  54. data/lib/puma/rack/builder.rb +6 -6
  55. data/lib/puma/rack/urlmap.rb +1 -1
  56. data/lib/puma/rack_default.rb +19 -4
  57. data/lib/puma/reactor.rb +19 -10
  58. data/lib/puma/request.rb +368 -169
  59. data/lib/puma/runner.rb +65 -22
  60. data/lib/puma/sd_notify.rb +146 -0
  61. data/lib/puma/server.rb +161 -102
  62. data/lib/puma/single.rb +13 -11
  63. data/lib/puma/state_file.rb +3 -6
  64. data/lib/puma/thread_pool.rb +71 -21
  65. data/lib/puma/util.rb +1 -12
  66. data/lib/puma.rb +9 -10
  67. data/lib/rack/handler/puma.rb +116 -86
  68. data/tools/Dockerfile +2 -2
  69. metadata +17 -12
  70. data/lib/puma/queue_close.rb +0 -26
  71. data/lib/puma/systemd.rb +0 -46
  72. data/lib/rack/version_restriction.rb +0 -15
data/lib/puma/dsl.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'puma/const'
4
- require 'puma/util'
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,10 +32,28 @@ 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
+ # | after_refork | :after_refork | inside |
51
+ #
35
52
  class DSL
36
- include ConfigDefault
53
+ ON_WORKER_KEY = [String, Symbol].freeze
37
54
 
38
- # convenience method so logic can be used in CI
55
+ # Convenience method so logic can be used in CI.
56
+ #
39
57
  # @see ssl_bind
40
58
  #
41
59
  def self.ssl_bind_str(host, port, opts)
@@ -49,28 +67,59 @@ module Puma
49
67
 
50
68
  ca_additions = "&ca=#{Puma::Util.escape(opts[:ca])}" if ['peer', 'force_peer'].include?(verify)
51
69
 
70
+ low_latency_str = opts.key?(:low_latency) ? "&low_latency=#{opts[:low_latency]}" : ''
52
71
  backlog_str = opts[:backlog] ? "&backlog=#{Integer(opts[:backlog])}" : ''
53
72
 
54
73
  if defined?(JRUBY_VERSION)
55
- ssl_cipher_list = opts[:ssl_cipher_list] ?
56
- "&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil
74
+ cipher_suites = opts[:ssl_cipher_list] ? "&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil # old name
75
+ cipher_suites = "#{cipher_suites}&cipher_suites=#{opts[:cipher_suites]}" if opts[:cipher_suites]
76
+ protocols = opts[:protocols] ? "&protocols=#{opts[:protocols]}" : nil
57
77
 
58
78
  keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
79
+ keystore_additions = "#{keystore_additions}&keystore-type=#{opts[:keystore_type]}" if opts[:keystore_type]
80
+ if opts[:truststore]
81
+ truststore_additions = "&truststore=#{opts[:truststore]}"
82
+ truststore_additions = "#{truststore_additions}&truststore-pass=#{opts[:truststore_pass]}" if opts[:truststore_pass]
83
+ truststore_additions = "#{truststore_additions}&truststore-type=#{opts[:truststore_type]}" if opts[:truststore_type]
84
+ end
59
85
 
60
- "ssl://#{host}:#{port}?#{keystore_additions}#{ssl_cipher_list}" \
86
+ "ssl://#{host}:#{port}?#{keystore_additions}#{truststore_additions}#{cipher_suites}#{protocols}" \
61
87
  "&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}"
62
88
  else
63
- ssl_cipher_filter = opts[:ssl_cipher_filter] ?
64
- "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
65
-
66
- v_flags = (ary = opts[:verification_flags]) ?
67
- "&verification_flags=#{Array(ary).join ','}" : nil
68
-
69
- cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(opts[:cert])}" : nil
70
- key_flags = (cert = opts[:key]) ? "&key=#{Puma::Util.escape(opts[:key])}" : nil
89
+ ssl_cipher_filter = opts[:ssl_cipher_filter] ? "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
90
+ ssl_ciphersuites = opts[:ssl_ciphersuites] ? "&ssl_ciphersuites=#{opts[:ssl_ciphersuites]}" : nil
91
+ v_flags = (ary = opts[:verification_flags]) ? "&verification_flags=#{Array(ary).join ','}" : nil
92
+
93
+ cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil
94
+ key_flags = (key = opts[:key]) ? "&key=#{Puma::Util.escape(key)}" : nil
95
+ password_flags = (password_command = opts[:key_password_command]) ? "&key_password_command=#{Puma::Util.escape(password_command)}" : nil
96
+
97
+ reuse_flag =
98
+ if (reuse = opts[:reuse])
99
+ if reuse == true
100
+ '&reuse=dflt'
101
+ elsif reuse.is_a?(Hash) && (reuse.key?(:size) || reuse.key?(:timeout))
102
+ val = +''
103
+ if (size = reuse[:size]) && Integer === size
104
+ val << size.to_s
105
+ end
106
+ if (timeout = reuse[:timeout]) && Integer === timeout
107
+ val << ",#{timeout}"
108
+ end
109
+ if val.empty?
110
+ nil
111
+ else
112
+ "&reuse=#{val}"
113
+ end
114
+ else
115
+ nil
116
+ end
117
+ else
118
+ nil
119
+ end
71
120
 
72
- "ssl://#{host}:#{port}?#{cert_flags}#{key_flags}" \
73
- "#{ssl_cipher_filter}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}"
121
+ "ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}#{ssl_ciphersuites}" \
122
+ "#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}#{low_latency_str}"
74
123
  end
75
124
  end
76
125
 
@@ -106,7 +155,7 @@ module Puma
106
155
  end
107
156
 
108
157
  def default_host
109
- @options[:default_host] || Configuration::DefaultTCPHost
158
+ @options[:default_host] || Configuration::DEFAULTS[:tcp_host]
110
159
  end
111
160
 
112
161
  def inject(&blk)
@@ -117,7 +166,10 @@ module Puma
117
166
  @options[key.to_sym] || default
118
167
  end
119
168
 
120
- # Load the named plugin for use by this configuration
169
+ # Load the named plugin for use by this configuration.
170
+ #
171
+ # @example
172
+ # plugin :tmp_restart
121
173
  #
122
174
  def plugin(name)
123
175
  @plugins << @config.load_plugin(name)
@@ -164,6 +216,7 @@ module Puma
164
216
  # activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' }
165
217
  # @example
166
218
  # activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true }
219
+ #
167
220
  def activate_control_app(url="auto", opts={})
168
221
  if url == "auto"
169
222
  path = Configuration.temp_path
@@ -189,8 +242,12 @@ module Puma
189
242
  @options[:control_url_umask] = opts[:umask] if opts[:umask]
190
243
  end
191
244
 
192
- # Load additional configuration from a file
193
- # Files get loaded later via Configuration#load
245
+ # Load additional configuration from a file.
246
+ # Files get loaded later via Configuration#load.
247
+ #
248
+ # @example
249
+ # load 'config/puma/production.rb'
250
+ #
194
251
  def load(file)
195
252
  @options[:config_files] ||= []
196
253
  @options[:config_files] << file
@@ -206,6 +263,7 @@ module Puma
206
263
  #
207
264
  # * Set the socket backlog depth with +backlog+, default is 1024.
208
265
  # * Set up an SSL certificate with +key+ & +cert+.
266
+ # * Set up an SSL certificate for mTLS with +key+, +cert+, +ca+ and +verify_mode+.
209
267
  # * Set whether to optimize for low latency instead of throughput with
210
268
  # +low_latency+, default is to not optimize for low latency. This is done
211
269
  # via +Socket::TCP_NODELAY+.
@@ -215,10 +273,13 @@ module Puma
215
273
  # bind 'unix:///var/run/puma.sock?backlog=512'
216
274
  # @example SSL cert
217
275
  # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem'
276
+ # @example SSL cert for mutual TLS (mTLS)
277
+ # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem&ca=ca.pem&verify_mode=force_peer'
218
278
  # @example Disable optimization for low latency
219
279
  # bind 'tcp://0.0.0.0:9292?low_latency=false'
220
280
  # @example Socket permissions
221
281
  # bind 'unix:///var/run/puma.sock?umask=0111'
282
+ #
222
283
  # @see Puma::Runner#load_and_bind
223
284
  # @see Puma::Cluster#run
224
285
  #
@@ -253,33 +314,70 @@ module Puma
253
314
  #
254
315
  # @example Only bind to systemd activated sockets, ignoring other binds
255
316
  # bind_to_activated_sockets 'only'
317
+ #
256
318
  def bind_to_activated_sockets(bind=true)
257
319
  @options[:bind_to_activated_sockets] = bind
258
320
  end
259
321
 
260
- # Define the TCP port to bind to. Use +bind+ for more advanced options.
322
+ # Define the TCP port to bind to. Use `bind` for more advanced options.
323
+ #
324
+ # The default is +9292+.
261
325
  #
262
326
  # @example
263
- # port 9292
327
+ # port 3000
328
+ #
264
329
  def port(port, host=nil)
265
330
  host ||= default_host
266
331
  bind URI::Generic.build(scheme: 'tcp', host: host, port: Integer(port)).to_s
267
332
  end
268
333
 
334
+ # Define how long the tcp socket stays open, if no data has been received.
335
+ #
336
+ # The default is 30 seconds.
337
+ #
338
+ # @example
339
+ # first_data_timeout 40
340
+ #
341
+ # @see Puma::Server.new
342
+ #
343
+ def first_data_timeout(seconds)
344
+ @options[:first_data_timeout] = Integer(seconds)
345
+ end
346
+
269
347
  # Define how long persistent connections can be idle before Puma closes them.
348
+ #
349
+ # The default is 20 seconds.
350
+ #
351
+ # @example
352
+ # persistent_timeout 30
353
+ #
270
354
  # @see Puma::Server.new
355
+ #
271
356
  def persistent_timeout(seconds)
272
357
  @options[:persistent_timeout] = Integer(seconds)
273
358
  end
274
359
 
275
- # Define how long the tcp socket stays open, if no data has been received.
360
+ # If a new request is not received within this number of seconds, begin shutting down.
361
+ #
362
+ # The default is +nil+.
363
+ #
364
+ # @example
365
+ # idle_timeout 60
366
+ #
276
367
  # @see Puma::Server.new
277
- def first_data_timeout(seconds)
278
- @options[:first_data_timeout] = Integer(seconds)
368
+ #
369
+ def idle_timeout(seconds)
370
+ @options[:idle_timeout] = Integer(seconds)
279
371
  end
280
372
 
281
373
  # Work around leaky apps that leave garbage in Thread locals
282
374
  # across requests.
375
+ #
376
+ # The default is +false+.
377
+ #
378
+ # @example
379
+ # clean_thread_locals
380
+ #
283
381
  def clean_thread_locals(which=true)
284
382
  @options[:clean_thread_locals] = which
285
383
  end
@@ -287,6 +385,7 @@ module Puma
287
385
  # When shutting down, drain the accept socket of pending connections and
288
386
  # process them. This loops over the accept socket until there are no more
289
387
  # read events and then stops looking and waits for the requests to finish.
388
+ #
290
389
  # @see Puma::Server#graceful_shutdown
291
390
  #
292
391
  def drain_on_shutdown(which=true)
@@ -300,18 +399,22 @@ module Puma
300
399
  #
301
400
  # @example
302
401
  # environment 'production'
402
+ #
303
403
  def environment(environment)
304
404
  @options[:environment] = environment
305
405
  end
306
406
 
307
- # How long to wait for threads to stop when shutting them
308
- # down. Defaults to :forever. Specifying :immediately will cause
309
- # Puma to kill the threads immediately. Otherwise the value
310
- # is the number of seconds to wait.
407
+ # How long to wait for threads to stop when shutting them down.
408
+ # Specifying :immediately will cause Puma to kill the threads immediately.
409
+ # Otherwise the value is the number of seconds to wait.
311
410
  #
312
411
  # Puma always waits a few seconds after killing a thread for it to try
313
412
  # to finish up it's work, even in :immediately mode.
413
+ #
414
+ # The default is +:forever+.
415
+ #
314
416
  # @see Puma::Server#graceful_shutdown
417
+ #
315
418
  def force_shutdown_after(val=:forever)
316
419
  i = case val
317
420
  when :forever
@@ -334,9 +437,9 @@ module Puma
334
437
  # on_restart do
335
438
  # puts 'On restart...'
336
439
  # end
440
+ #
337
441
  def on_restart(&block)
338
- @options[:on_restart] ||= []
339
- @options[:on_restart] << block
442
+ process_hook :on_restart, nil, block, 'on_restart'
340
443
  end
341
444
 
342
445
  # Command to use to restart Puma. This should be just how to
@@ -345,6 +448,7 @@ module Puma
345
448
  #
346
449
  # @example
347
450
  # restart_command '/u/app/lolcat/bin/restart_puma'
451
+ #
348
452
  def restart_command(cmd)
349
453
  @options[:restart_cmd] = cmd.to_s
350
454
  end
@@ -353,26 +457,49 @@ module Puma
353
457
  #
354
458
  # @example
355
459
  # pidfile '/u/apps/lolcat/tmp/pids/puma.pid'
460
+ #
356
461
  def pidfile(path)
357
462
  @options[:pidfile] = path.to_s
358
463
  end
359
464
 
360
- # Disable request logging, if this isn't used it'll be enabled by default.
465
+ # Disable request logging, the inverse of `log_requests`.
466
+ #
467
+ # The default is +true+.
361
468
  #
362
469
  # @example
363
470
  # quiet
471
+ #
364
472
  def quiet(which=true)
365
473
  @options[:log_requests] = !which
366
474
  end
367
475
 
368
- # Enable request logging
476
+ # Enable request logging, the inverse of `quiet`.
477
+ #
478
+ # The default is +false+.
479
+ #
480
+ # @example
481
+ # log_requests
369
482
  #
370
483
  def log_requests(which=true)
371
484
  @options[:log_requests] = which
372
485
  end
373
486
 
487
+ # Pass in a custom logging class instance
488
+ #
489
+ # @example
490
+ # custom_logger Logger.new('t.log')
491
+ #
492
+ def custom_logger(custom_logger)
493
+ @options[:custom_logger] = custom_logger
494
+ end
495
+
374
496
  # Show debugging info
375
497
  #
498
+ # The default is +false+.
499
+ #
500
+ # @example
501
+ # debug
502
+ #
376
503
  def debug
377
504
  @options[:debug] = true
378
505
  end
@@ -383,6 +510,7 @@ module Puma
383
510
  #
384
511
  # @example
385
512
  # rackup '/u/apps/lolcat/config.ru'
513
+ #
386
514
  def rackup(path)
387
515
  @options[:rackup] ||= path.to_s
388
516
  end
@@ -390,21 +518,32 @@ module Puma
390
518
  # Allows setting `env['rack.url_scheme']`.
391
519
  # Only necessary if X-Forwarded-Proto is not being set by your proxy
392
520
  # Normal values are 'http' or 'https'.
521
+ #
393
522
  def rack_url_scheme(scheme=nil)
394
523
  @options[:rack_url_scheme] = scheme
395
524
  end
396
525
 
526
+ # Enable HTTP 103 Early Hints responses.
527
+ #
528
+ # The default is +nil+.
529
+ #
530
+ # @example
531
+ # early_hints
532
+ #
397
533
  def early_hints(answer=true)
398
534
  @options[:early_hints] = answer
399
535
  end
400
536
 
401
537
  # Redirect +STDOUT+ and +STDERR+ to files specified. The +append+ parameter
402
- # specifies whether the output is appended, the default is +false+.
538
+ # specifies whether the output is appended.
539
+ #
540
+ # The default is +false+.
403
541
  #
404
542
  # @example
405
543
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr'
406
544
  # @example
407
545
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr', true
546
+ #
408
547
  def stdout_redirect(stdout=nil, stderr=nil, append=false)
409
548
  @options[:redirect_stdout] = stdout
410
549
  @options[:redirect_stderr] = stderr
@@ -415,8 +554,9 @@ module Puma
415
554
  @options[:log_formatter] = block
416
555
  end
417
556
 
418
- # Configure +min+ to be the minimum number of threads to use to answer
419
- # requests and +max+ the maximum.
557
+ # Configure the number of threads to use to answer requests.
558
+ #
559
+ # It can be a single fixed number, or a +min+ and a +max+.
420
560
  #
421
561
  # The default is the environment variables +PUMA_MIN_THREADS+ / +PUMA_MAX_THREADS+
422
562
  # (or +MIN_THREADS+ / +MAX_THREADS+ if the +PUMA_+ variables aren't set).
@@ -424,10 +564,13 @@ module Puma
424
564
  # If these environment variables aren't set, the default is "0, 5" in MRI or "0, 16" for other interpreters.
425
565
  #
426
566
  # @example
567
+ # threads 5
568
+ # @example
427
569
  # threads 0, 16
428
570
  # @example
429
571
  # threads 5, 5
430
- def threads(min, max)
572
+ #
573
+ def threads(min, max = min)
431
574
  min = Integer(min)
432
575
  max = Integer(max)
433
576
  if min > max
@@ -452,13 +595,25 @@ module Puma
452
595
  # Puma will assume you are using the +localhost+ gem and try to load the
453
596
  # appropriate files.
454
597
  #
598
+ # When using the options hash parameter, the `reuse:` value is either
599
+ # `true`, which sets reuse 'on' with default values, or a hash, with `:size`
600
+ # and/or `:timeout` keys, each with integer values.
601
+ #
602
+ # The `cert:` options hash parameter can be the path to a certificate
603
+ # file including all intermediate certificates in PEM format.
604
+ #
605
+ # The `cert_pem:` options hash parameter can be String containing the
606
+ # cerificate and all intermediate certificates in PEM format.
607
+ #
455
608
  # @example
456
609
  # ssl_bind '127.0.0.1', '9292', {
457
610
  # cert: path_to_cert,
458
611
  # key: path_to_key,
459
612
  # ssl_cipher_filter: cipher_filter, # optional
613
+ # ssl_ciphersuites: ciphersuites, # optional
460
614
  # verify_mode: verify_mode, # default 'none'
461
615
  # verification_flags: flags, # optional, not supported by JRuby
616
+ # reuse: true # optional
462
617
  # }
463
618
  #
464
619
  # @example Using self-signed certificate with the +localhost+ gem:
@@ -468,6 +623,7 @@ module Puma
468
623
  # ssl_bind '127.0.0.1', '9292', {
469
624
  # cert_pem: File.read(path_to_cert),
470
625
  # key_pem: File.read(path_to_key),
626
+ # reuse: {size: 2_000, timeout: 20} # optional
471
627
  # }
472
628
  #
473
629
  # @example For JRuby, two keys are required: +keystore+ & +keystore_pass+
@@ -477,6 +633,7 @@ module Puma
477
633
  # ssl_cipher_list: cipher_list, # optional
478
634
  # verify_mode: verify_mode # default 'none'
479
635
  # }
636
+ #
480
637
  def ssl_bind(host, port, opts = {})
481
638
  add_pem_values_to_options_store(opts)
482
639
  bind self.class.ssl_bind_str(host, port, opts)
@@ -487,6 +644,7 @@ module Puma
487
644
  #
488
645
  # @example
489
646
  # state_path '/u/apps/lolcat/tmp/pids/puma.state'
647
+ #
490
648
  def state_path(path)
491
649
  @options[:state] = path.to_s
492
650
  end
@@ -495,6 +653,7 @@ module Puma
495
653
  #
496
654
  # @example
497
655
  # state_permission 0600
656
+ #
498
657
  # @version 5.0.0
499
658
  #
500
659
  def state_permission(permission)
@@ -508,7 +667,12 @@ module Puma
508
667
  # set, otherwise 0.
509
668
  #
510
669
  # @note Cluster mode only.
670
+ #
671
+ # @example
672
+ # workers 2
673
+ #
511
674
  # @see Puma::Cluster
675
+ #
512
676
  def workers(count)
513
677
  @options[:workers] = count.to_i
514
678
  end
@@ -526,11 +690,28 @@ module Puma
526
690
  #
527
691
  # Moving from workers = 1 to workers = 0 will save 10-30% of memory use.
528
692
  #
693
+ # The default is +false+.
694
+ #
529
695
  # @note Cluster mode only.
696
+ #
697
+ # @example
698
+ # silence_single_worker_warning
699
+ #
530
700
  def silence_single_worker_warning
531
701
  @options[:silence_single_worker_warning] = true
532
702
  end
533
703
 
704
+ # Disable warning message when running single mode with callback hook defined.
705
+ #
706
+ # The default is +false+.
707
+ #
708
+ # @example
709
+ # silence_fork_callback_warning
710
+ #
711
+ def silence_fork_callback_warning
712
+ @options[:silence_fork_callback_warning] = true
713
+ end
714
+
534
715
  # Code to run immediately before master process
535
716
  # forks workers (once on boot). These hooks can block if necessary
536
717
  # to wait for background operations unknown to Puma to finish before
@@ -541,13 +722,16 @@ module Puma
541
722
  # This can be called multiple times to add several hooks.
542
723
  #
543
724
  # @note Cluster mode only.
725
+ #
544
726
  # @example
545
727
  # before_fork do
546
728
  # puts "Starting workers..."
547
729
  # end
730
+ #
548
731
  def before_fork(&block)
549
- @options[:before_fork] ||= []
550
- @options[:before_fork] << block
732
+ warn_if_in_single_mode('before_fork')
733
+
734
+ process_hook :before_fork, nil, block, 'before_fork'
551
735
  end
552
736
 
553
737
  # Code to run in a worker when it boots to setup
@@ -556,30 +740,37 @@ module Puma
556
740
  # This can be called multiple times to add several hooks.
557
741
  #
558
742
  # @note Cluster mode only.
743
+ #
559
744
  # @example
560
745
  # on_worker_boot do
561
746
  # puts 'Before worker boot...'
562
747
  # end
563
- def on_worker_boot(&block)
564
- @options[:before_worker_boot] ||= []
565
- @options[:before_worker_boot] << block
748
+ #
749
+ def on_worker_boot(key = nil, &block)
750
+ warn_if_in_single_mode('on_worker_boot')
751
+
752
+ process_hook :before_worker_boot, key, block, 'on_worker_boot'
566
753
  end
567
754
 
568
755
  # Code to run immediately before a worker shuts
569
- # down (after it has finished processing HTTP requests). These hooks
756
+ # down (after it has finished processing HTTP requests). The worker's
757
+ # index is passed as an argument. These hooks
570
758
  # can block if necessary to wait for background operations unknown
571
759
  # to Puma to finish before the process terminates.
572
760
  #
573
761
  # This can be called multiple times to add several hooks.
574
762
  #
575
763
  # @note Cluster mode only.
764
+ #
576
765
  # @example
577
766
  # on_worker_shutdown do
578
767
  # puts 'On worker shutdown...'
579
768
  # end
580
- def on_worker_shutdown(&block)
581
- @options[:before_worker_shutdown] ||= []
582
- @options[:before_worker_shutdown] << block
769
+ #
770
+ def on_worker_shutdown(key = nil, &block)
771
+ warn_if_in_single_mode('on_worker_shutdown')
772
+
773
+ process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
583
774
  end
584
775
 
585
776
  # Code to run in the master right before a worker is started. The worker's
@@ -588,13 +779,16 @@ module Puma
588
779
  # This can be called multiple times to add several hooks.
589
780
  #
590
781
  # @note Cluster mode only.
782
+ #
591
783
  # @example
592
784
  # on_worker_fork do
593
785
  # puts 'Before worker fork...'
594
786
  # end
787
+ #
595
788
  def on_worker_fork(&block)
596
- @options[:before_worker_fork] ||= []
597
- @options[:before_worker_fork] << block
789
+ warn_if_in_single_mode('on_worker_fork')
790
+
791
+ process_hook :before_worker_fork, nil, block, 'on_worker_fork'
598
792
  end
599
793
 
600
794
  # Code to run in the master after a worker has been started. The worker's
@@ -603,17 +797,42 @@ module Puma
603
797
  # This is called everytime a worker is to be started.
604
798
  #
605
799
  # @note Cluster mode only.
800
+ #
606
801
  # @example
607
802
  # after_worker_fork do
608
803
  # puts 'After worker fork...'
609
804
  # end
805
+ #
610
806
  def after_worker_fork(&block)
611
- @options[:after_worker_fork] ||= []
612
- @options[:after_worker_fork] << block
807
+ warn_if_in_single_mode('after_worker_fork')
808
+
809
+ process_hook :after_worker_fork, nil, block, 'after_worker_fork'
613
810
  end
614
811
 
615
812
  alias_method :after_worker_boot, :after_worker_fork
616
813
 
814
+ # Code to run after puma is booted (works for both: single and clustered)
815
+ #
816
+ # @example
817
+ # on_booted do
818
+ # puts 'After booting...'
819
+ # end
820
+ #
821
+ def on_booted(&block)
822
+ @config.options[:events].on_booted(&block)
823
+ end
824
+
825
+ # Code to run after puma is stopped (works for both: single and clustered)
826
+ #
827
+ # @example
828
+ # on_stopped do
829
+ # puts 'After stopping...'
830
+ # end
831
+ #
832
+ def on_stopped(&block)
833
+ @config.options[:events].on_stopped(&block)
834
+ end
835
+
617
836
  # When `fork_worker` is enabled, code to run in Worker 0
618
837
  # before all other workers are re-forked from this process,
619
838
  # after the server has temporarily stopped serving requests
@@ -626,15 +845,84 @@ module Puma
626
845
  # This can be called multiple times to add several hooks.
627
846
  #
628
847
  # @note Cluster mode with `fork_worker` enabled only.
848
+ #
629
849
  # @example
630
850
  # on_refork do
631
851
  # 3.times {GC.start}
632
852
  # end
853
+ #
633
854
  # @version 5.0.0
634
855
  #
635
- def on_refork(&block)
636
- @options[:before_refork] ||= []
637
- @options[:before_refork] << block
856
+ def on_refork(key = nil, &block)
857
+ warn_if_in_single_mode('on_refork')
858
+
859
+ process_hook :before_refork, key, block, 'on_refork'
860
+ end
861
+
862
+ # When `fork_worker` is enabled, code to run in Worker 0
863
+ # after all other workers are re-forked from this process,
864
+ # after the server has temporarily stopped serving requests
865
+ # (once per complete refork cycle).
866
+ #
867
+ # This can be used to re-open any connections to remote servers
868
+ # (database, Redis, ...) that were closed via on_refork.
869
+ #
870
+ # This can be called multiple times to add several hooks.
871
+ #
872
+ # @note Cluster mode with `fork_worker` enabled only.
873
+ #
874
+ # @example
875
+ # after_refork do
876
+ # puts 'After refork...'
877
+ # end
878
+ #
879
+ def after_refork(key = nil, &block)
880
+ process_hook :after_refork, key, block, 'after_refork'
881
+ end
882
+
883
+ # Provide a block to be executed just before a thread is added to the thread
884
+ # pool. Be careful: while the block executes, thread creation is delayed, and
885
+ # probably a request will have to wait too! The new thread will not be added to
886
+ # the threadpool until the provided block returns.
887
+ #
888
+ # Return values are ignored.
889
+ # Raising an exception will log a warning.
890
+ #
891
+ # This hook is useful for doing something when the thread pool grows.
892
+ #
893
+ # This can be called multiple times to add several hooks.
894
+ #
895
+ # @example
896
+ # on_thread_start do
897
+ # puts 'On thread start...'
898
+ # end
899
+ #
900
+ def on_thread_start(&block)
901
+ process_hook :before_thread_start, nil, block, 'on_thread_start'
902
+ end
903
+
904
+ # Provide a block to be executed after a thread is trimmed from the thread
905
+ # pool. Be careful: while this block executes, Puma's main loop is
906
+ # blocked, so no new requests will be picked up.
907
+ #
908
+ # This hook only runs when a thread in the threadpool is trimmed by Puma.
909
+ # It does not run when a thread dies due to exceptions or any other cause.
910
+ #
911
+ # Return values are ignored.
912
+ # Raising an exception will log a warning.
913
+ #
914
+ # This hook is useful for cleaning up thread local resources when a thread
915
+ # is trimmed.
916
+ #
917
+ # This can be called multiple times to add several hooks.
918
+ #
919
+ # @example
920
+ # on_thread_exit do
921
+ # puts 'On thread exit...'
922
+ # end
923
+ #
924
+ def on_thread_exit(&block)
925
+ process_hook :before_thread_exit, nil, block, 'on_thread_exit'
638
926
  end
639
927
 
640
928
  # Code to run out-of-band when the worker is idle.
@@ -646,9 +934,9 @@ module Puma
646
934
  # or scheduling asynchronous tasks to execute after a response.
647
935
  #
648
936
  # This can be called multiple times to add several hooks.
937
+ #
649
938
  def out_of_band(&block)
650
- @options[:out_of_band] ||= []
651
- @options[:out_of_band] << block
939
+ process_hook :out_of_band, nil, block, 'out_of_band'
652
940
  end
653
941
 
654
942
  # The directory to operate out of.
@@ -657,16 +945,21 @@ module Puma
657
945
  #
658
946
  # @example
659
947
  # directory '/u/apps/lolcat'
948
+ #
660
949
  def directory(dir)
661
950
  @options[:directory] = dir.to_s
662
951
  end
663
952
 
664
953
  # Preload the application before starting the workers; this conflicts with
665
- # phased restart feature. On by default if your app uses more than 1 worker.
954
+ # phased restart feature.
955
+ #
956
+ # The default is +true+ if your app uses more than 1 worker.
666
957
  #
667
958
  # @note Cluster mode only.
959
+ #
668
960
  # @example
669
961
  # preload_app!
962
+ #
670
963
  def preload_app!(answer=true)
671
964
  @options[:preload_app] = answer
672
965
  end
@@ -678,6 +971,7 @@ module Puma
678
971
  # lowlevel_error_handler do |err|
679
972
  # [200, {}, ["error page"]]
680
973
  # end
974
+ #
681
975
  def lowlevel_error_handler(obj=nil, &block)
682
976
  obj ||= block
683
977
  raise "Provide either a #call'able or a block" unless obj
@@ -697,23 +991,26 @@ module Puma
697
991
  # new Bundler context and thus can float around as the release
698
992
  # dictates.
699
993
  #
700
- # @see extra_runtime_dependencies
701
- #
702
994
  # @note This is incompatible with +preload_app!+.
703
995
  # @note This is only supported for RubyGems 2.2+
996
+ #
997
+ # @see extra_runtime_dependencies
998
+ #
704
999
  def prune_bundler(answer=true)
705
1000
  @options[:prune_bundler] = answer
706
1001
  end
707
1002
 
708
- # By default, Puma will raise SignalException when SIGTERM is received. In
709
- # environments where SIGTERM is something expected, you can suppress these
710
- # with this option.
1003
+ # Raises a SignalException when SIGTERM is received. In environments where
1004
+ # SIGTERM is something expected, you can suppress these with this option.
711
1005
  #
712
1006
  # This can be useful for example in Kubernetes, where rolling restart is
713
- # guaranteed usually on infrastructure level.
1007
+ # guaranteed usually on the infrastructure level.
1008
+ #
1009
+ # The default is +true+.
714
1010
  #
715
1011
  # @example
716
1012
  # raise_exception_on_sigterm false
1013
+ #
717
1014
  # @see Puma::Launcher#setup_signals
718
1015
  # @see Puma::Cluster#setup_signals
719
1016
  #
@@ -732,6 +1029,7 @@ module Puma
732
1029
  # extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
733
1030
  # @example
734
1031
  # extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
1032
+ #
735
1033
  # @see Puma::Launcher#extra_runtime_deps_directories
736
1034
  #
737
1035
  def extra_runtime_dependencies(answer = [])
@@ -743,21 +1041,26 @@ module Puma
743
1041
  # If you do not specify a tag, Puma will infer it. If you do not want Puma
744
1042
  # to add a tag, use an empty string.
745
1043
  #
1044
+ # The default is the current file or directory base name.
1045
+ #
746
1046
  # @example
747
1047
  # tag 'app name'
748
1048
  # @example
749
1049
  # tag ''
1050
+ #
750
1051
  def tag(string)
751
1052
  @options[:tag] = string.to_s
752
1053
  end
753
1054
 
754
1055
  # Change the default interval for checking workers.
755
1056
  #
756
- # The default value is 5 seconds.
1057
+ # The default is 5 seconds.
757
1058
  #
758
1059
  # @note Cluster mode only.
1060
+ #
759
1061
  # @example
760
- # worker_check_interval 5
1062
+ # worker_check_interval 10
1063
+ #
761
1064
  # @see Puma::Cluster#check_workers
762
1065
  #
763
1066
  def worker_check_interval(interval)
@@ -769,16 +1072,20 @@ module Puma
769
1072
  # not a request timeout, it is to protect against a hung or dead process.
770
1073
  # Setting this value will not protect against slow requests.
771
1074
  #
772
- # The minimum value is 6 seconds, the default value is 60 seconds.
1075
+ # This value must be greater than worker_check_interval.
1076
+ #
1077
+ # The default is 60 seconds.
773
1078
  #
774
1079
  # @note Cluster mode only.
1080
+ #
775
1081
  # @example
776
1082
  # worker_timeout 60
1083
+ #
777
1084
  # @see Puma::Cluster::Worker#ping_timeout
778
1085
  #
779
1086
  def worker_timeout(timeout)
780
1087
  timeout = Integer(timeout)
781
- min = @options.fetch(:worker_check_interval, Puma::ConfigDefault::DefaultWorkerCheckInterval)
1088
+ min = @options.fetch(:worker_check_interval, Configuration::DEFAULTS[:worker_check_interval])
782
1089
 
783
1090
  if timeout <= min
784
1091
  raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})"
@@ -789,12 +1096,13 @@ module Puma
789
1096
 
790
1097
  # Change the default worker timeout for booting.
791
1098
  #
792
- # If unspecified, this defaults to the value of worker_timeout.
1099
+ # The default is the value of `worker_timeout`.
793
1100
  #
794
1101
  # @note Cluster mode only.
795
1102
  #
796
1103
  # @example
797
1104
  # worker_boot_timeout 60
1105
+ #
798
1106
  # @see Puma::Cluster::Worker#ping_timeout
799
1107
  #
800
1108
  def worker_boot_timeout(timeout)
@@ -803,7 +1111,13 @@ module Puma
803
1111
 
804
1112
  # Set the timeout for worker shutdown.
805
1113
  #
1114
+ # The default is 60 seconds.
1115
+ #
806
1116
  # @note Cluster mode only.
1117
+ #
1118
+ # @example
1119
+ # worker_shutdown_timeout 90
1120
+ #
807
1121
  # @see Puma::Cluster::Worker#term
808
1122
  #
809
1123
  def worker_shutdown_timeout(timeout)
@@ -819,9 +1133,13 @@ module Puma
819
1133
  # 2. **:oldest** - the oldest workers (i.e. the workers that were started
820
1134
  # the longest time ago) will be culled.
821
1135
  #
1136
+ # The default is +:youngest+.
1137
+ #
822
1138
  # @note Cluster mode only.
1139
+ #
823
1140
  # @example
824
1141
  # worker_culling_strategy :oldest
1142
+ #
825
1143
  # @see Puma::Cluster#cull_workers
826
1144
  #
827
1145
  def worker_culling_strategy(strategy)
@@ -834,7 +1152,7 @@ module Puma
834
1152
  @options[:worker_culling_strategy] = strategy
835
1153
  end
836
1154
 
837
- # When set to true (the default), workers accept all requests
1155
+ # When set to true, workers accept all requests
838
1156
  # and queue them before passing them to the handlers.
839
1157
  # When set to false, each worker process accepts exactly as
840
1158
  # many requests as it is configured to simultaneously handle.
@@ -847,7 +1165,11 @@ module Puma
847
1165
  # slow clients will occupy a handler thread while the request
848
1166
  # is being sent. A reverse proxy, such as nginx, can handle
849
1167
  # slow clients and queue requests before they reach Puma.
1168
+ #
1169
+ # The default is +true+.
1170
+ #
850
1171
  # @see Puma::Server
1172
+ #
851
1173
  def queue_requests(answer=true)
852
1174
  @options[:queue_requests] = answer
853
1175
  end
@@ -865,9 +1187,13 @@ module Puma
865
1187
  # listening on the socket, allowing workers which are not processing any
866
1188
  # requests to pick up new requests first.
867
1189
  #
1190
+ # The default is 0.005 seconds.
1191
+ #
868
1192
  # Only works on MRI. For all other interpreters, this setting does nothing.
1193
+ #
869
1194
  # @see Puma::Server#handle_servers
870
1195
  # @see Puma::ThreadPool#wait_for_less_busy_worker
1196
+ #
871
1197
  # @version 5.0.0
872
1198
  #
873
1199
  def wait_for_less_busy_worker(val=0.005)
@@ -881,14 +1207,17 @@ module Puma
881
1207
  #
882
1208
  # There are 5 possible values:
883
1209
  #
884
- # 1. **:socket** (the default) - read the peername from the socket using the
885
- # syscall. This is the normal behavior.
1210
+ # 1. **:socket** - read the peername from the socket using the
1211
+ # syscall. This is the normal behavior. If this fails for any reason (e.g.,
1212
+ # if the peer disconnects between the connection being accepted and the getpeername
1213
+ # system call), Puma will return "0.0.0.0"
886
1214
  # 2. **:localhost** - set the remote address to "127.0.0.1"
887
1215
  # 3. **header: <http_header>**- set the remote address to the value of the
888
1216
  # provided http header. For instance:
889
1217
  # `set_remote_address header: "X-Real-IP"`.
890
1218
  # 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.
1219
+ # headers such as X-Forwarded-For to be used as well. If this header is absent,
1220
+ # Puma will fall back to the behavior of :socket
892
1221
  # 4. **proxy_protocol: :v1**- set the remote address to the value read from the
893
1222
  # HAproxy PROXY protocol, version 1. If the request does not have the PROXY
894
1223
  # protocol attached to it, will fall back to :socket
@@ -896,6 +1225,11 @@ module Puma
896
1225
  # you wish. Because Puma never uses this field anyway, it's format is
897
1226
  # entirely in your hands.
898
1227
  #
1228
+ # The default is +:socket+.
1229
+ #
1230
+ # @example
1231
+ # set_remote_address :localhost
1232
+ #
899
1233
  def set_remote_address(val=:socket)
900
1234
  case val
901
1235
  when :socket
@@ -936,34 +1270,49 @@ module Puma
936
1270
  # (default 1000), or pass 0 to disable auto refork.
937
1271
  #
938
1272
  # @note Cluster mode only.
1273
+ #
939
1274
  # @version 5.0.0
940
1275
  #
941
1276
  def fork_worker(after_requests=1000)
942
1277
  @options[:fork_worker] = Integer(after_requests)
943
1278
  end
944
1279
 
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.
1280
+ # The number of requests to attempt inline before sending a client back to
1281
+ # the reactor to be subject to normal ordering.
948
1282
  #
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.
1283
+ # The default is 10.
954
1284
  #
955
- # @see Puma::Cluster#nakayoshi_gc
956
- # @version 5.0.0
1285
+ # @example
1286
+ # max_fast_inline 20
957
1287
  #
958
- def nakayoshi_fork(enabled=true)
959
- @options[:nakayoshi_fork] = enabled
1288
+ def max_fast_inline(num_of_requests)
1289
+ @options[:max_fast_inline] = Float(num_of_requests)
960
1290
  end
961
1291
 
962
- # The number of requests to attempt inline before sending a client back to
963
- # the reactor to be subject to normal ordering.
1292
+ # When `true`, keep-alive connections are maintained on inbound requests.
1293
+ # Enabling this setting reduces the number of TCP operations, reducing response
1294
+ # times for connections that can send multiple requests in a single connection.
964
1295
  #
965
- def max_fast_inline(num_of_requests)
966
- @options[:max_fast_inline] = Float(num_of_requests)
1296
+ # When Puma receives more incoming connections than available Puma threads,
1297
+ # enabling the keep-alive behavior may result in processing requests out-of-order,
1298
+ # increasing overall response time variance. Increased response time variance
1299
+ # means that the overall average of response times might not change, but more
1300
+ # outliers will exist. Those long-tail outliers may significantly affect response
1301
+ # times for some processed requests.
1302
+ #
1303
+ # When `false`, Puma closes the connection after each request, requiring the
1304
+ # client to open a new request. Disabling this setting guarantees that requests
1305
+ # will be processed in the order they are fully received, decreasing response
1306
+ # variance and eliminating long-tail outliers caused by keep-alive behavior.
1307
+ # The trade-off is that the number of TCP operations required will increase.
1308
+ #
1309
+ # The default is +true+.
1310
+ #
1311
+ # @example
1312
+ # enable_keep_alives false
1313
+ #
1314
+ def enable_keep_alives(enabled=true)
1315
+ @options[:enable_keep_alives] = enabled
967
1316
  end
968
1317
 
969
1318
  # Specify the backend for the IO selector.
@@ -985,14 +1334,72 @@ module Puma
985
1334
  @options[:io_selector_backend] = backend.to_sym
986
1335
  end
987
1336
 
1337
+ # Ensures +STDOUT+ and +STDERR+ is immediately flushed to the underlying
1338
+ # operating system and is not buffered internally
1339
+ #
1340
+ # The default is +true+.
1341
+ #
1342
+ # @example
1343
+ # mutate_stdout_and_stderr_to_sync_on_write false
1344
+ #
988
1345
  def mutate_stdout_and_stderr_to_sync_on_write(enabled=true)
989
1346
  @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled
990
1347
  end
991
1348
 
1349
+ # Specify how big the request payload should be, in bytes.
1350
+ # This limit is compared against Content-Length HTTP header.
1351
+ # If the payload size (CONTENT_LENGTH) is larger than http_content_length_limit,
1352
+ # HTTP 413 status code is returned.
1353
+ #
1354
+ # When no Content-Length http header is present, it is compared against the
1355
+ # size of the body of the request.
1356
+ #
1357
+ # The default is +nil+.
1358
+ #
1359
+ # @example
1360
+ # http_content_length_limit 2_000_000_000
1361
+ #
1362
+ def http_content_length_limit(limit)
1363
+ @options[:http_content_length_limit] = limit
1364
+ end
1365
+
1366
+ # Supported http methods, which will replace `Puma::Const::SUPPORTED_HTTP_METHODS`.
1367
+ # The value of `:any` will allows all methods, otherwise, the value must be
1368
+ # an array of strings. Note that methods are all uppercase.
1369
+ #
1370
+ # `Puma::Const::SUPPORTED_HTTP_METHODS` is conservative, if you want a
1371
+ # complete set of methods, the methods defined by the
1372
+ # [IANA Method Registry](https://www.iana.org/assignments/http-methods/http-methods.xhtml)
1373
+ # are pre-defined as the constant `Puma::Const::IANA_HTTP_METHODS`.
1374
+ #
1375
+ # @note If the `methods` value is `:any`, no method check with be performed,
1376
+ # similar to Puma v5 and earlier.
1377
+ #
1378
+ # @example Adds 'PROPFIND' to existing supported methods
1379
+ # supported_http_methods(Puma::Const::SUPPORTED_HTTP_METHODS + ['PROPFIND'])
1380
+ # @example Restricts methods to the array elements
1381
+ # supported_http_methods %w[HEAD GET POST PUT DELETE OPTIONS PROPFIND]
1382
+ # @example Restricts methods to the methods in the IANA Registry
1383
+ # supported_http_methods Puma::Const::IANA_HTTP_METHODS
1384
+ # @example Allows any method
1385
+ # supported_http_methods :any
1386
+ #
1387
+ def supported_http_methods(methods)
1388
+ if methods == :any
1389
+ @options[:supported_http_methods] = :any
1390
+ elsif Array === methods && methods == (ary = methods.grep(String).uniq) &&
1391
+ !ary.empty?
1392
+ @options[:supported_http_methods] = ary
1393
+ else
1394
+ raise "supported_http_methods must be ':any' or a unique array of strings"
1395
+ end
1396
+ end
1397
+
992
1398
  private
993
1399
 
994
1400
  # To avoid adding cert_pem and key_pem as URI params, we store them on the
995
1401
  # options[:store] from where Puma binder knows how to find and extract them.
1402
+ #
996
1403
  def add_pem_values_to_options_store(opts)
997
1404
  return if defined?(JRUBY_VERSION)
998
1405
 
@@ -1008,5 +1415,31 @@ module Puma
1008
1415
  end
1009
1416
  end
1010
1417
  end
1418
+
1419
+ def process_hook(options_key, key, block, meth)
1420
+ @options[options_key] ||= []
1421
+ if ON_WORKER_KEY.include? key.class
1422
+ @options[options_key] << [block, key.to_sym]
1423
+ elsif key.nil?
1424
+ @options[options_key] << block
1425
+ else
1426
+ raise "'#{meth}' key must be String or Symbol"
1427
+ end
1428
+ end
1429
+
1430
+ def warn_if_in_single_mode(hook_name)
1431
+ return if @options[:silence_fork_callback_warning]
1432
+ # user_options (CLI) have precedence over config file
1433
+ workers_val = @config.options.user_options[:workers] || @options[:workers] ||
1434
+ @config.puma_default_options[:workers] || 0
1435
+ if workers_val == 0
1436
+ log_string =
1437
+ "Warning: You specified code to run in a `#{hook_name}` block, " \
1438
+ "but Puma is not configured to run in cluster mode (worker count > 0), " \
1439
+ "so your `#{hook_name}` block will not run."
1440
+
1441
+ LogWriter.stdio.log(log_string)
1442
+ end
1443
+ end
1011
1444
  end
1012
1445
  end