puma 3.12.6 → 4.3.12

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.

Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +155 -3
  3. data/LICENSE +0 -0
  4. data/README.md +76 -48
  5. data/bin/puma-wild +0 -0
  6. data/docs/architecture.md +1 -0
  7. data/docs/deployment.md +24 -4
  8. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  9. data/docs/images/puma-connection-flow.png +0 -0
  10. data/docs/images/puma-general-arch.png +0 -0
  11. data/docs/nginx.md +0 -0
  12. data/docs/plugins.md +20 -10
  13. data/docs/restart.md +4 -2
  14. data/docs/signals.md +0 -0
  15. data/docs/systemd.md +27 -9
  16. data/docs/tcp_mode.md +96 -0
  17. data/ext/puma_http11/PumaHttp11Service.java +2 -0
  18. data/ext/puma_http11/ext_help.h +0 -0
  19. data/ext/puma_http11/extconf.rb +21 -0
  20. data/ext/puma_http11/http11_parser.c +58 -70
  21. data/ext/puma_http11/http11_parser.h +0 -0
  22. data/ext/puma_http11/http11_parser.java.rl +21 -37
  23. data/ext/puma_http11/http11_parser.rl +0 -0
  24. data/ext/puma_http11/http11_parser_common.rl +4 -4
  25. data/ext/puma_http11/io_buffer.c +0 -0
  26. data/ext/puma_http11/mini_ssl.c +138 -33
  27. data/ext/puma_http11/org/jruby/puma/Http11.java +106 -114
  28. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +86 -99
  29. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
  30. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +15 -4
  31. data/ext/puma_http11/puma_http11.c +3 -0
  32. data/lib/puma/accept_nonblock.rb +7 -1
  33. data/lib/puma/app/status.rb +37 -29
  34. data/lib/puma/binder.rb +38 -60
  35. data/lib/puma/cli.rb +4 -0
  36. data/lib/puma/client.rb +285 -208
  37. data/lib/puma/cluster.rb +53 -30
  38. data/lib/puma/commonlogger.rb +0 -0
  39. data/lib/puma/configuration.rb +4 -3
  40. data/lib/puma/const.rb +26 -20
  41. data/lib/puma/control_cli.rb +30 -5
  42. data/lib/puma/detect.rb +0 -0
  43. data/lib/puma/dsl.rb +299 -75
  44. data/lib/puma/events.rb +4 -1
  45. data/lib/puma/io_buffer.rb +1 -6
  46. data/lib/puma/jruby_restart.rb +0 -0
  47. data/lib/puma/launcher.rb +95 -53
  48. data/lib/puma/minissl/context_builder.rb +76 -0
  49. data/lib/puma/minissl.rb +35 -17
  50. data/lib/puma/null_io.rb +0 -0
  51. data/lib/puma/plugin/tmp_restart.rb +2 -0
  52. data/lib/puma/plugin.rb +5 -2
  53. data/lib/puma/rack/builder.rb +2 -0
  54. data/lib/puma/rack/urlmap.rb +2 -0
  55. data/lib/puma/rack_default.rb +2 -0
  56. data/lib/puma/reactor.rb +110 -57
  57. data/lib/puma/runner.rb +11 -3
  58. data/lib/puma/server.rb +89 -61
  59. data/lib/puma/single.rb +3 -3
  60. data/lib/puma/state_file.rb +0 -0
  61. data/lib/puma/tcp_logger.rb +0 -0
  62. data/lib/puma/thread_pool.rb +15 -33
  63. data/lib/puma/util.rb +1 -6
  64. data/lib/puma.rb +8 -0
  65. data/lib/rack/handler/puma.rb +3 -3
  66. data/tools/docker/Dockerfile +16 -0
  67. data/tools/jungle/README.md +0 -0
  68. data/tools/jungle/init.d/README.md +0 -0
  69. data/tools/jungle/init.d/puma +6 -6
  70. data/tools/jungle/rc.d/README.md +0 -0
  71. data/tools/jungle/rc.d/puma.conf +0 -0
  72. data/tools/jungle/upstart/README.md +0 -0
  73. data/tools/jungle/upstart/puma-manager.conf +0 -0
  74. data/tools/jungle/upstart/puma.conf +0 -0
  75. data/tools/trickletest.rb +0 -1
  76. metadata +26 -13
  77. data/lib/puma/compat.rb +0 -14
  78. data/lib/puma/convenient.rb +0 -25
  79. data/lib/puma/daemon_ext.rb +0 -33
  80. data/lib/puma/delegation.rb +0 -13
  81. data/lib/puma/java_io_buffer.rb +0 -47
  82. data/lib/puma/rack/backports/uri/common_193.rb +0 -33
data/lib/puma/dsl.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'puma/const'
4
+
3
5
  module Puma
4
- # The methods that are available for use inside the config file.
6
+ # The methods that are available for use inside the configuration file.
5
7
  # These same methods are used in Puma cli and the rack handler
6
8
  # internally.
7
9
  #
@@ -26,7 +28,8 @@ module Puma
26
28
  # puts config.options[:binds]
27
29
  # # => "tcp://127.0.0.1:3002"
28
30
  #
29
- # Detailed docs can be found in `examples/config.rb`
31
+ # You can also find many examples being used by the test suite in
32
+ # +test/config+.
30
33
  class DSL
31
34
  include ConfigDefault
32
35
 
@@ -79,9 +82,22 @@ module Puma
79
82
  @plugins << @config.load_plugin(name)
80
83
  end
81
84
 
82
- # Use +obj+ or +block+ as the Rack app. This allows a config file to
83
- # be the app itself.
85
+ # Use an object or block as the rack application. This allows the
86
+ # configuration file to be the application itself.
87
+ #
88
+ # @example
89
+ # app do |env|
90
+ # body = 'Hello, World!'
84
91
  #
92
+ # [
93
+ # 200,
94
+ # {
95
+ # 'Content-Type' => 'text/plain',
96
+ # 'Content-Length' => body.length.to_s
97
+ # },
98
+ # [body]
99
+ # ]
100
+ # end
85
101
  def app(obj=nil, &block)
86
102
  obj ||= block
87
103
 
@@ -90,9 +106,20 @@ module Puma
90
106
  @options[:app] = obj
91
107
  end
92
108
 
93
- # Start the Puma control rack app on +url+. This app can be communicated
94
- # with to control the main server.
109
+ # Start the Puma control rack application on +url+. This application can
110
+ # be communicated with to control the main server. Additionally, you can
111
+ # provide an authentication token, so all requests to the control server
112
+ # will need to include that token as a query parameter. This allows for
113
+ # simple authentication.
114
+ #
115
+ # Check out {Puma::App::Status} to see what the app has available.
95
116
  #
117
+ # @example
118
+ # activate_control_app 'unix:///var/run/pumactl.sock'
119
+ # @example
120
+ # activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' }
121
+ # @example
122
+ # activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true }
96
123
  def activate_control_app(url="auto", opts={})
97
124
  if url == "auto"
98
125
  path = Configuration.temp_path
@@ -103,7 +130,12 @@ module Puma
103
130
  end
104
131
 
105
132
  if opts[:no_token]
106
- auth_token = :none
133
+ # We need to use 'none' rather than :none because this value will be
134
+ # passed on to an instance of OptionParser, which doesn't support
135
+ # symbols as option values.
136
+ #
137
+ # See: https://github.com/puma/puma/issues/1193#issuecomment-305995488
138
+ auth_token = 'none'
107
139
  else
108
140
  auth_token = opts[:auth_token]
109
141
  auth_token ||= Configuration.random_token
@@ -120,22 +152,29 @@ module Puma
120
152
  @options[:config_files] << file
121
153
  end
122
154
 
123
- # Adds a binding for the server to +url+. tcp://, unix://, and ssl:// are the only accepted
124
- # protocols. Use query parameters within the url to specify options.
155
+ # Bind the server to +url+. "tcp://", "unix://" and "ssl://" are the only
156
+ # accepted protocols. Multiple urls can be bound to, calling `bind` does
157
+ # not overwrite previous bindings.
125
158
  #
126
- # @note multiple urls can be bound to, calling `bind` does not overwrite previous bindings.
159
+ # The default is "tcp://0.0.0.0:9292".
127
160
  #
128
- # @example Explicitly the socket backlog depth (default is 1024)
129
- # bind('unix:///var/run/puma.sock?backlog=2048')
161
+ # You can use query parameters within the url to specify options:
130
162
  #
131
- # @example Set up ssl cert
132
- # bind('ssl://127.0.0.1:9292?key=key.key&cert=cert.pem')
163
+ # - Set the socket backlog depth with +backlog+, default is 1024.
164
+ # - Set up an SSL certificate with +key+ & +cert+.
165
+ # - Set whether to optimize for low latency instead of throughput with
166
+ # +low_latency+, default is to optimize for low latency. This is done
167
+ # via +Socket::TCP_NODELAY+.
168
+ # - Set socket permissions with +umask+.
133
169
  #
134
- # @example Prefer low-latency over higher throughput (via `Socket::TCP_NODELAY`)
135
- # bind('tcp://0.0.0.0:9292?low_latency=true')
136
- #
137
- # @example Set socket permissions
138
- # bind('unix:///var/run/puma.sock?umask=0111')
170
+ # @example Backlog depth
171
+ # bind 'unix:///var/run/puma.sock?backlog=512'
172
+ # @example SSL cert
173
+ # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem'
174
+ # @example Disable optimization for low latency
175
+ # bind 'tcp://0.0.0.0:9292?low_latency=false'
176
+ # @example Socket permissions
177
+ # bind 'unix:///var/run/puma.sock?umask=0111'
139
178
  def bind(url)
140
179
  @options[:binds] ||= []
141
180
  @options[:binds] << url
@@ -147,33 +186,40 @@ module Puma
147
186
 
148
187
  # Define the TCP port to bind to. Use +bind+ for more advanced options.
149
188
  #
189
+ # @example
190
+ # port 9292
150
191
  def port(port, host=nil)
151
192
  host ||= default_host
152
193
  bind "tcp://#{host}:#{port}"
153
194
  end
154
195
 
155
- # Define how long persistent connections can be idle before puma closes
156
- # them
157
- #
196
+ # Define how long persistent connections can be idle before Puma closes
197
+ # them.
158
198
  def persistent_timeout(seconds)
159
199
  @options[:persistent_timeout] = Integer(seconds)
160
200
  end
161
201
 
162
- # Define how long the tcp socket stays open, if no data has been received
163
- #
202
+ # Define how long the tcp socket stays open, if no data has been received.
164
203
  def first_data_timeout(seconds)
165
204
  @options[:first_data_timeout] = Integer(seconds)
166
205
  end
167
206
 
168
207
  # Work around leaky apps that leave garbage in Thread locals
169
- # across requests
170
- #
208
+ # across requests.
171
209
  def clean_thread_locals(which=true)
172
210
  @options[:clean_thread_locals] = which
173
211
  end
174
212
 
175
- # Daemonize the server into the background. Highly suggest that
176
- # this be combined with +pidfile+ and +stdout_redirect+.
213
+ # Daemonize the server into the background. It's highly recommended to
214
+ # use this in combination with +pidfile+ and +stdout_redirect+.
215
+ #
216
+ # The default is "false".
217
+ #
218
+ # @example
219
+ # daemonize
220
+ #
221
+ # @example
222
+ # daemonize false
177
223
  def daemonize(which=true)
178
224
  @options[:daemon] = which
179
225
  end
@@ -186,7 +232,13 @@ module Puma
186
232
  @options[:drain_on_shutdown] = which
187
233
  end
188
234
 
189
- # Set the environment in which the Rack's app will run.
235
+ # Set the environment in which the rack's app will run. The value must be
236
+ # a string.
237
+ #
238
+ # The default is "development".
239
+ #
240
+ # @example
241
+ # environment 'production'
190
242
  def environment(environment)
191
243
  @options[:environment] = environment
192
244
  end
@@ -212,30 +264,41 @@ module Puma
212
264
  end
213
265
 
214
266
  # Code to run before doing a restart. This code should
215
- # close logfiles, database connections, etc.
267
+ # close log files, database connections, etc.
216
268
  #
217
269
  # This can be called multiple times to add code each time.
218
270
  #
271
+ # @example
272
+ # on_restart do
273
+ # puts 'On restart...'
274
+ # end
219
275
  def on_restart(&block)
220
276
  @options[:on_restart] ||= []
221
277
  @options[:on_restart] << block
222
278
  end
223
279
 
224
- # Command to use to restart puma. This should be just how to
225
- # load puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
226
- # to puma, as those are the same as the original process.
280
+ # Command to use to restart Puma. This should be just how to
281
+ # load Puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
282
+ # to Puma, as those are the same as the original process.
227
283
  #
284
+ # @example
285
+ # restart_command '/u/app/lolcat/bin/restart_puma'
228
286
  def restart_command(cmd)
229
287
  @options[:restart_cmd] = cmd.to_s
230
288
  end
231
289
 
232
- # Store the pid of the server in the file at +path+.
290
+ # Store the pid of the server in the file at "path".
291
+ #
292
+ # @example
293
+ # pidfile '/u/apps/lolcat/tmp/pids/puma.pid'
233
294
  def pidfile(path)
234
295
  @options[:pidfile] = path.to_s
235
296
  end
236
297
 
237
- # Disable request logging.
298
+ # Disable request logging, if this isn't used it'll be enabled by default.
238
299
  #
300
+ # @example
301
+ # quiet
239
302
  def quiet(which=true)
240
303
  @options[:log_requests] = !which
241
304
  end
@@ -254,6 +317,10 @@ module Puma
254
317
 
255
318
  # Load +path+ as a rackup file.
256
319
  #
320
+ # The default is "config.ru".
321
+ #
322
+ # @example
323
+ # rackup '/u/apps/lolcat/config.ru'
257
324
  def rackup(path)
258
325
  @options[:rackup] = path.to_s
259
326
  end
@@ -268,16 +335,32 @@ module Puma
268
335
  @options[:early_hints] = answer
269
336
  end
270
337
 
271
- # Redirect STDOUT and STDERR to files specified.
338
+ # Redirect STDOUT and STDERR to files specified. The +append+ parameter
339
+ # specifies whether the output is appended, the default is +false+.
340
+ #
341
+ # @example
342
+ # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr'
343
+ # @example
344
+ # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr', true
272
345
  def stdout_redirect(stdout=nil, stderr=nil, append=false)
273
346
  @options[:redirect_stdout] = stdout
274
347
  @options[:redirect_stderr] = stderr
275
348
  @options[:redirect_append] = append
276
349
  end
277
350
 
351
+ def log_formatter(&block)
352
+ @options[:log_formatter] = block
353
+ end
354
+
278
355
  # Configure +min+ to be the minimum number of threads to use to answer
279
356
  # requests and +max+ the maximum.
280
357
  #
358
+ # The default is "0, 16".
359
+ #
360
+ # @example
361
+ # threads 0, 16
362
+ # @example
363
+ # threads 5, 5
281
364
  def threads(min, max)
282
365
  min = Integer(min)
283
366
  max = Integer(max)
@@ -293,81 +376,135 @@ module Puma
293
376
  @options[:max_threads] = max
294
377
  end
295
378
 
379
+ # Instead of "bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path'" you
380
+ # can also use the "ssl_bind" option.
381
+ #
382
+ # @example
383
+ # ssl_bind '127.0.0.1', '9292', {
384
+ # cert: path_to_cert,
385
+ # key: path_to_key,
386
+ # ssl_cipher_filter: cipher_filter, # optional
387
+ # verify_mode: verify_mode, # default 'none'
388
+ # }
389
+ # @example For JRuby additional keys are required: keystore & keystore_pass.
390
+ # ssl_bind '127.0.0.1', '9292', {
391
+ # cert: path_to_cert,
392
+ # key: path_to_key,
393
+ # ssl_cipher_filter: cipher_filter, # optional
394
+ # verify_mode: verify_mode, # default 'none'
395
+ # keystore: path_to_keystore,
396
+ # keystore_pass: password
397
+ # }
296
398
  def ssl_bind(host, port, opts)
297
- verify = opts.fetch(:verify_mode, 'none')
399
+ verify = opts.fetch(:verify_mode, 'none').to_s
400
+ no_tlsv1 = opts.fetch(:no_tlsv1, 'false')
401
+ no_tlsv1_1 = opts.fetch(:no_tlsv1_1, 'false')
402
+ ca_additions = "&ca=#{opts[:ca]}" if ['peer', 'force_peer'].include?(verify)
298
403
 
299
404
  if defined?(JRUBY_VERSION)
300
405
  keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
301
- bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}&verify_mode=#{verify}"
406
+ bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}&verify_mode=#{verify}&no_tlsv1=#{no_tlsv1}&no_tlsv1_1=#{no_tlsv1_1}#{ca_additions}"
302
407
  else
303
- bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&verify_mode=#{verify}"
408
+ ssl_cipher_filter = "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" if opts[:ssl_cipher_filter]
409
+ bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}#{ssl_cipher_filter}&verify_mode=#{verify}&no_tlsv1=#{no_tlsv1}&no_tlsv1_1=#{no_tlsv1_1}#{ca_additions}"
304
410
  end
305
411
  end
306
412
 
307
413
  # Use +path+ as the file to store the server info state. This is
308
- # used by pumactl to query and control the server.
414
+ # used by +pumactl+ to query and control the server.
309
415
  #
416
+ # @example
417
+ # state_path '/u/apps/lolcat/tmp/pids/puma.state'
310
418
  def state_path(path)
311
419
  @options[:state] = path.to_s
312
420
  end
313
421
 
314
- # *Cluster mode only* How many worker processes to run.
422
+ # How many worker processes to run. Typically this is set to
423
+ # to the number of available cores.
315
424
  #
425
+ # The default is 0.
426
+ #
427
+ # @note Cluster mode only.
316
428
  def workers(count)
317
429
  @options[:workers] = count.to_i
318
430
  end
319
431
 
320
- # *Cluster mode only* Code to run immediately before master process
432
+ # Code to run immediately before master process
321
433
  # forks workers (once on boot). These hooks can block if necessary
322
- # to wait for background operations unknown to puma to finish before
434
+ # to wait for background operations unknown to Puma to finish before
323
435
  # the process terminates.
324
- # This can be used to close any connections to remote servers (database, redis, ...)
325
- # that were opened when preloading the code
436
+ # This can be used to close any connections to remote servers (database,
437
+ # Redis, ...) that were opened when preloading the code.
326
438
  #
327
- # This can be called multiple times to add hooks.
439
+ # This can be called multiple times to add several hooks.
328
440
  #
441
+ # @note Cluster mode only.
442
+ # @example
443
+ # before_fork do
444
+ # puts "Starting workers..."
445
+ # end
329
446
  def before_fork(&block)
330
447
  @options[:before_fork] ||= []
331
448
  @options[:before_fork] << block
332
449
  end
333
450
 
334
- # *Cluster mode only* Code to run in a worker when it boots to setup
451
+ # Code to run in a worker when it boots to setup
335
452
  # the process before booting the app.
336
453
  #
337
- # This can be called multiple times to add hooks.
454
+ # This can be called multiple times to add several hooks.
338
455
  #
456
+ # @note Cluster mode only.
457
+ # @example
458
+ # on_worker_fork do
459
+ # puts 'Before worker fork...'
460
+ # end
339
461
  def on_worker_boot(&block)
340
462
  @options[:before_worker_boot] ||= []
341
463
  @options[:before_worker_boot] << block
342
464
  end
343
465
 
344
- # *Cluster mode only* Code to run immediately before a worker shuts
466
+ # Code to run immediately before a worker shuts
345
467
  # down (after it has finished processing HTTP requests). These hooks
346
468
  # can block if necessary to wait for background operations unknown
347
- # to puma to finish before the process terminates.
469
+ # to Puma to finish before the process terminates.
348
470
  #
349
- # This can be called multiple times to add hooks.
471
+ # This can be called multiple times to add several hooks.
350
472
  #
473
+ # @note Cluster mode only.
474
+ # @example
475
+ # on_worker_shutdown do
476
+ # puts 'On worker shutdown...'
477
+ # end
351
478
  def on_worker_shutdown(&block)
352
479
  @options[:before_worker_shutdown] ||= []
353
480
  @options[:before_worker_shutdown] << block
354
481
  end
355
482
 
356
- # *Cluster mode only* Code to run in the master when it is
357
- # about to create the worker by forking itself.
483
+ # Code to run in the master right before a worker is started. The worker's
484
+ # index is passed as an argument.
358
485
  #
359
- # This can be called multiple times to add hooks.
486
+ # This can be called multiple times to add several hooks.
360
487
  #
488
+ # @note Cluster mode only.
489
+ # @example
490
+ # on_worker_fork do
491
+ # puts 'Before worker fork...'
492
+ # end
361
493
  def on_worker_fork(&block)
362
494
  @options[:before_worker_fork] ||= []
363
495
  @options[:before_worker_fork] << block
364
496
  end
365
497
 
366
- # *Cluster mode only* Code to run in the master after it starts
367
- # a worker.
498
+ # Code to run in the master after a worker has been started. The worker's
499
+ # index is passed as an argument.
368
500
  #
369
- # This can be called multiple times to add hooks.
501
+ # This is called everytime a worker is to be started.
370
502
  #
503
+ # @note Cluster mode only.
504
+ # @example
505
+ # after_worker_fork do
506
+ # puts 'After worker fork...'
507
+ # end
371
508
  def after_worker_fork(&block)
372
509
  @options[:after_worker_fork] ||= []
373
510
  @options[:after_worker_fork] = block
@@ -375,7 +512,26 @@ module Puma
375
512
 
376
513
  alias_method :after_worker_boot, :after_worker_fork
377
514
 
515
+ # Code to run out-of-band when the worker is idle.
516
+ # These hooks run immediately after a request has finished
517
+ # processing and there are no busy threads on the worker.
518
+ # The worker doesn't accept new requests until this code finishes.
519
+ #
520
+ # This hook is useful for running out-of-band garbage collection
521
+ # or scheduling asynchronous tasks to execute after a response.
522
+ #
523
+ # This can be called multiple times to add several hooks.
524
+ def out_of_band(&block)
525
+ @options[:out_of_band] ||= []
526
+ @options[:out_of_band] << block
527
+ end
528
+
378
529
  # The directory to operate out of.
530
+ #
531
+ # The default is the current directory.
532
+ #
533
+ # @example
534
+ # directory '/u/apps/lolcat'
379
535
  def directory(dir)
380
536
  @options[:directory] = dir.to_s
381
537
  end
@@ -386,22 +542,28 @@ module Puma
386
542
  directory dir
387
543
  end
388
544
 
389
- # Run the app as a raw TCP app instead of an HTTP rack app
545
+ # Run the app as a raw TCP app instead of an HTTP rack app.
390
546
  def tcp_mode
391
547
  @options[:mode] = :tcp
392
548
  end
393
549
 
394
- # *Cluster mode only* Preload the application before starting
395
- # the workers and setting up the listen ports. This conflicts
396
- # with using the phased restart feature, you can't use both.
550
+ # Preload the application before starting the workers; this conflicts with
551
+ # phased restart feature. This is off by default.
397
552
  #
553
+ # @note Cluster mode only.
554
+ # @example
555
+ # preload_app!
398
556
  def preload_app!(answer=true)
399
557
  @options[:preload_app] = answer
400
558
  end
401
559
 
402
- # Use +obj+ or +block+ as the low level error handler. This allows a config file to
403
- # change the default error on the server.
560
+ # Use +obj+ or +block+ as the low level error handler. This allows the
561
+ # configuration file to change the default error on the server.
404
562
  #
563
+ # @example
564
+ # lowlevel_error_handler do |err|
565
+ # [200, {}, ["error page"]]
566
+ # end
405
567
  def lowlevel_error_handler(obj=nil, &block)
406
568
  obj ||= block
407
569
  raise "Provide either a #call'able or a block" unless obj
@@ -411,38 +573,100 @@ module Puma
411
573
  # This option is used to allow your app and its gems to be
412
574
  # properly reloaded when not using preload.
413
575
  #
414
- # When set, if puma detects that it's been invoked in the
576
+ # When set, if Puma detects that it's been invoked in the
415
577
  # context of Bundler, it will cleanup the environment and
416
578
  # re-run itself outside the Bundler environment, but directly
417
579
  # using the files that Bundler has setup.
418
580
  #
419
- # This means that puma is now decoupled from your Bundler
581
+ # This means that Puma is now decoupled from your Bundler
420
582
  # context and when each worker loads, it will be loading a
421
583
  # new Bundler context and thus can float around as the release
422
584
  # dictates.
585
+ #
586
+ # See also: extra_runtime_dependencies
587
+ #
588
+ # @note This is incompatible with +preload_app!+.
589
+ # @note This is only supported for RubyGems 2.2+
423
590
  def prune_bundler(answer=true)
424
591
  @options[:prune_bundler] = answer
425
592
  end
426
593
 
427
- # Additional text to display in process listing
594
+ # By default, Puma will raise SignalException when SIGTERM is received. In
595
+ # environments where SIGTERM is something expected, you can suppress these
596
+ # with this option.
597
+ #
598
+ # This can be useful for example in Kubernetes, where rolling restart is
599
+ # guaranteed usually on infrastructure level.
600
+ #
601
+ # @example
602
+ # raise_exception_on_sigterm false
603
+ def raise_exception_on_sigterm(answer=true)
604
+ @options[:raise_exception_on_sigterm] = answer
605
+ end
606
+
607
+ # When using prune_bundler, if extra runtime dependencies need to be loaded to
608
+ # initialize your app, then this setting can be used. This includes any Puma plugins.
609
+ #
610
+ # Before bundler is pruned, the gem names supplied will be looked up in the bundler
611
+ # context and then loaded again after bundler is pruned.
612
+ # Only applies if prune_bundler is used.
613
+ #
614
+ # @example
615
+ # extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
616
+ # @example
617
+ # extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
618
+ def extra_runtime_dependencies(answer = [])
619
+ @options[:extra_runtime_dependencies] = Array(answer)
620
+ end
621
+
622
+ # Additional text to display in process listing.
623
+ #
624
+ # If you do not specify a tag, Puma will infer it. If you do not want Puma
625
+ # to add a tag, use an empty string.
626
+ #
627
+ # @example
628
+ # tag 'app name'
629
+ # @example
630
+ # tag ''
428
631
  def tag(string)
429
632
  @options[:tag] = string.to_s
430
633
  end
431
634
 
432
- # *Cluster mode only* Set the timeout for workers in seconds
433
- # When set the master process will terminate any workers
434
- # that have not checked in within the given +timeout+.
435
- # This mitigates hung processes. Default value is 60 seconds.
635
+ # Verifies that all workers have checked in to the master process within
636
+ # the given timeout. If not the worker process will be restarted. This is
637
+ # not a request timeout, it is to protect against a hung or dead process.
638
+ # Setting this value will not protect against slow requests.
639
+ #
640
+ # The minimum value is 6 seconds, the default value is 60 seconds.
641
+ #
642
+ # @note Cluster mode only.
643
+ # @example
644
+ # worker_timeout 60
436
645
  def worker_timeout(timeout)
437
- @options[:worker_timeout] = Integer(timeout)
646
+ timeout = Integer(timeout)
647
+ min = Const::WORKER_CHECK_INTERVAL
648
+
649
+ if timeout <= min
650
+ raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})"
651
+ end
652
+
653
+ @options[:worker_timeout] = timeout
438
654
  end
439
655
 
440
- # *Cluster mode only* Set the timeout for workers to boot
656
+ # Change the default worker timeout for booting.
657
+ #
658
+ # If unspecified, this defaults to the value of worker_timeout.
659
+ #
660
+ # @note Cluster mode only.
661
+ # @example:
662
+ # worker_boot_timeout 60
441
663
  def worker_boot_timeout(timeout)
442
664
  @options[:worker_boot_timeout] = Integer(timeout)
443
665
  end
444
666
 
445
- # *Cluster mode only* Set the timeout for worker shutdown
667
+ # Set the timeout for worker shutdown
668
+ #
669
+ # @note Cluster mode only.
446
670
  def worker_shutdown_timeout(timeout)
447
671
  @options[:worker_shutdown_timeout] = Integer(timeout)
448
672
  end
@@ -459,7 +683,7 @@ module Puma
459
683
  # Note that setting this to false disables HTTP keepalive and
460
684
  # slow clients will occupy a handler thread while the request
461
685
  # is being sent. A reverse proxy, such as nginx, can handle
462
- # slow clients and queue requests before they reach puma.
686
+ # slow clients and queue requests before they reach Puma.
463
687
  def queue_requests(answer=true)
464
688
  @options[:queue_requests] = answer
465
689
  end
@@ -488,7 +712,7 @@ module Puma
488
712
  # is used, allowing headers such as X-Forwarded-For
489
713
  # to be used as well.
490
714
  # * Any string - this allows you to hardcode remote address to any value
491
- # you wish. Because puma never uses this field anyway, it's
715
+ # you wish. Because Puma never uses this field anyway, it's
492
716
  # format is entirely in your hands.
493
717
  def set_remote_address(val=:socket)
494
718
  case val
data/lib/puma/events.rb CHANGED
@@ -93,7 +93,10 @@ module Puma
93
93
  # parsing exception.
94
94
  #
95
95
  def parse_error(server, env, error)
96
- @stderr.puts "#{Time.now}: HTTP parse error, malformed request (#{env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR]}): #{error.inspect}\n---\n"
96
+ @stderr.puts "#{Time.now}: HTTP parse error, malformed request " \
97
+ "(#{env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR]}#{env[REQUEST_PATH]}): " \
98
+ "#{error.inspect}" \
99
+ "\n---\n"
97
100
  end
98
101
 
99
102
  # An SSL error has occurred.
@@ -1,9 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'puma/detect'
4
-
5
- if Puma.jruby?
6
- require 'puma/java_io_buffer'
7
- else
8
- require 'puma/puma_http11'
9
- end
4
+ require 'puma/puma_http11'
File without changes