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/server.rb CHANGED
@@ -6,21 +6,16 @@ require 'puma/thread_pool'
6
6
  require 'puma/const'
7
7
  require 'puma/events'
8
8
  require 'puma/null_io'
9
- require 'puma/compat'
10
9
  require 'puma/reactor'
11
10
  require 'puma/client'
12
11
  require 'puma/binder'
13
- require 'puma/delegation'
14
12
  require 'puma/accept_nonblock'
15
13
  require 'puma/util'
16
14
 
17
15
  require 'puma/puma_http11'
18
16
 
19
- unless Puma.const_defined? "IOBuffer"
20
- require 'puma/io_buffer'
21
- end
22
-
23
17
  require 'socket'
18
+ require 'forwardable'
24
19
 
25
20
  module Puma
26
21
 
@@ -28,7 +23,7 @@ module Puma
28
23
  #
29
24
  # This class is used by the `Puma::Single` and `Puma::Cluster` classes
30
25
  # to generate one or more `Puma::Server` instances capable of handling requests.
31
- # Each Puma process will contain one `Puma::Server` instacne.
26
+ # Each Puma process will contain one `Puma::Server` instance.
32
27
  #
33
28
  # The `Puma::Server` instance pulls requests from the socket, adds them to a
34
29
  # `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.
@@ -37,7 +32,7 @@ module Puma
37
32
  class Server
38
33
 
39
34
  include Puma::Const
40
- extend Puma::Delegation
35
+ extend Forwardable
41
36
 
42
37
  attr_reader :thread
43
38
  attr_reader :events
@@ -79,7 +74,6 @@ module Puma
79
74
  @first_data_timeout = options.fetch(:first_data_timeout, FIRST_DATA_TIMEOUT)
80
75
 
81
76
  @binder = Binder.new(events)
82
- @own_binder = true
83
77
 
84
78
  @leak_stack_on_error = true
85
79
 
@@ -95,14 +89,10 @@ module Puma
95
89
 
96
90
  attr_accessor :binder, :leak_stack_on_error, :early_hints
97
91
 
98
- forward :add_tcp_listener, :@binder
99
- forward :add_ssl_listener, :@binder
100
- forward :add_unix_listener, :@binder
101
- forward :connected_port, :@binder
92
+ def_delegators :@binder, :add_tcp_listener, :add_ssl_listener, :add_unix_listener, :connected_port
102
93
 
103
94
  def inherit_binder(bind)
104
95
  @binder = bind
105
- @own_binder = false
106
96
  end
107
97
 
108
98
  def tcp_mode!
@@ -214,7 +204,10 @@ module Puma
214
204
  @events.fire :state, :running
215
205
 
216
206
  if background
217
- @thread = Thread.new { handle_servers_lopez_mode }
207
+ @thread = Thread.new do
208
+ Puma.set_thread_name "server"
209
+ handle_servers_lopez_mode
210
+ end
218
211
  return @thread
219
212
  else
220
213
  handle_servers_lopez_mode
@@ -270,10 +263,11 @@ module Puma
270
263
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
271
264
  end
272
265
 
273
- @notify.close
274
-
275
- if @status != :restart and @own_binder
276
- @binder.close
266
+ # Prevent can't modify frozen IOError (RuntimeError)
267
+ begin
268
+ @notify.close
269
+ rescue IOError
270
+ # no biggy
277
271
  end
278
272
  end
279
273
 
@@ -323,9 +317,13 @@ module Puma
323
317
 
324
318
  @events.ssl_error self, addr, cert, e
325
319
  rescue HttpParserError => e
326
- client.write_400
320
+ client.write_error(400)
327
321
  client.close
328
322
 
323
+ @events.parse_error self, client.env, e
324
+ rescue HttpParserError501 => e
325
+ client.write_error(501)
326
+ client.close
329
327
  @events.parse_error self, client.env, e
330
328
  rescue ConnectionError, EOFError
331
329
  client.close
@@ -357,7 +355,10 @@ module Puma
357
355
  @events.fire :state, :running
358
356
 
359
357
  if background
360
- @thread = Thread.new { handle_servers }
358
+ @thread = Thread.new do
359
+ Puma.set_thread_name "server"
360
+ handle_servers
361
+ end
361
362
  return @thread
362
363
  else
363
364
  handle_servers
@@ -398,7 +399,10 @@ module Puma
398
399
  end
399
400
 
400
401
  pool << client
401
- pool.wait_until_not_full
402
+ busy_threads = pool.wait_until_not_full
403
+ if busy_threads == 0
404
+ @options[:out_of_band].each(&:call) if @options[:out_of_band]
405
+ end
402
406
  end
403
407
  rescue SystemCallError
404
408
  # nothing
@@ -430,10 +434,6 @@ module Puma
430
434
  ensure
431
435
  @check.close
432
436
  @notify.close
433
-
434
- if @status != :restart and @own_binder
435
- @binder.close
436
- end
437
437
  end
438
438
 
439
439
  @events.fire :state, :done
@@ -487,15 +487,20 @@ module Puma
487
487
 
488
488
  requests += 1
489
489
 
490
- check_for_more_data = @status == :run
490
+ # Closing keepalive sockets after they've made a reasonable
491
+ # number of requests allows Puma to service many connections
492
+ # fairly, even when the number of concurrent connections exceeds
493
+ # the size of the threadpool. It also allows cluster mode Pumas
494
+ # to keep load evenly distributed across workers, because clients
495
+ # are randomly assigned a new worker when opening a new connection.
496
+ #
497
+ # Previously, Puma would kick connections in this conditional back
498
+ # to the reactor. However, because this causes the todo set to increase
499
+ # in size, the wait_until_full mutex would never unlock, leaving
500
+ # any additional connections unserviced.
501
+ break if requests >= MAX_FAST_INLINE
491
502
 
492
- if requests >= MAX_FAST_INLINE
493
- # This will mean that reset will only try to use the data it already
494
- # has buffered and won't try to read more data. What this means is that
495
- # every client, independent of their request speed, gets treated like a slow
496
- # one once every MAX_FAST_INLINE requests.
497
- check_for_more_data = false
498
- end
503
+ check_for_more_data = @status == :run
499
504
 
500
505
  unless client.reset(check_for_more_data)
501
506
  close_socket = false
@@ -526,15 +531,20 @@ module Puma
526
531
  rescue HttpParserError => e
527
532
  lowlevel_error(e, client.env)
528
533
 
529
- client.write_400
534
+ client.write_error(400)
530
535
 
531
536
  @events.parse_error self, client.env, e
537
+ rescue HttpParserError501 => e
538
+ lowlevel_error(e, client.env)
532
539
 
540
+ client.write_error(501)
541
+
542
+ @events.parse_error self, client.env, e
533
543
  # Server error
534
544
  rescue StandardError => e
535
545
  lowlevel_error(e, client.env)
536
546
 
537
- client.write_500
547
+ client.write_error(500)
538
548
 
539
549
  @events.unknown_error self, e, "Read"
540
550
 
@@ -609,19 +619,26 @@ module Puma
609
619
  end
610
620
 
611
621
  def default_server_port(env)
612
- return PORT_443 if env[HTTPS_KEY] == 'on' || env[HTTPS_KEY] == 'https'
613
- env['HTTP_X_FORWARDED_PROTO'] == 'https' ? PORT_443 : PORT_80
622
+ if ['on', HTTPS].include?(env[HTTPS_KEY]) || env[HTTP_X_FORWARDED_PROTO].to_s[0...5] == HTTPS || env[HTTP_X_FORWARDED_SCHEME] == HTTPS || env[HTTP_X_FORWARDED_SSL] == "on"
623
+ PORT_443
624
+ else
625
+ PORT_80
626
+ end
614
627
  end
615
628
 
616
- # Given the request +env+ from +client+ and a partial request body
617
- # in +body+, finish reading the body if there is one and invoke
618
- # the rack app. Then construct the response and write it back to
619
- # +client+
629
+ # Takes the request +req+, invokes the Rack application to construct
630
+ # the response and writes it back to +req.io+.
620
631
  #
621
- # +cl+ is the previously fetched Content-Length header if there
622
- # was one. This is an optimization to keep from having to look
623
- # it up again.
632
+ # The second parameter +lines+ is a IO-like object unique to this thread.
633
+ # This is normally an instance of Puma::IOBuffer.
624
634
  #
635
+ # It'll return +false+ when the connection is closed, this doesn't mean
636
+ # that the response wasn't successful.
637
+ #
638
+ # It'll return +:async+ if the connection remains open but will be handled
639
+ # elsewhere, i.e. the connection has been hijacked by the Rack application.
640
+ #
641
+ # Finally, it'll return +true+ on keep-alive connections.
625
642
  def handle_request(req, lines)
626
643
  env = req.env
627
644
  client = req.io
@@ -644,24 +661,28 @@ module Puma
644
661
  head = env[REQUEST_METHOD] == HEAD
645
662
 
646
663
  env[RACK_INPUT] = body
647
- env[RACK_URL_SCHEME] = env[HTTPS_KEY] ? HTTPS : HTTP
664
+ env[RACK_URL_SCHEME] = default_server_port(env) == PORT_443 ? HTTPS : HTTP
648
665
 
649
666
  if @early_hints
650
667
  env[EARLY_HINTS] = lambda { |headers|
651
- fast_write client, "HTTP/1.1 103 Early Hints\r\n".freeze
668
+ begin
669
+ fast_write client, "HTTP/1.1 103 Early Hints\r\n".freeze
652
670
 
653
- headers.each_pair do |k, vs|
654
- if vs.respond_to?(:to_s) && !vs.to_s.empty?
655
- vs.to_s.split(NEWLINE).each do |v|
656
- next if possible_header_injection?(v)
657
- fast_write client, "#{k}: #{v}\r\n"
671
+ headers.each_pair do |k, vs|
672
+ if vs.respond_to?(:to_s) && !vs.to_s.empty?
673
+ vs.to_s.split(NEWLINE).each do |v|
674
+ next if possible_header_injection?(v)
675
+ fast_write client, "#{k}: #{v}\r\n"
676
+ end
677
+ else
678
+ fast_write client, "#{k}: #{vs}\r\n"
658
679
  end
659
- else
660
- fast_write client, "#{k}: #{vs}\r\n"
661
680
  end
662
- end
663
681
 
664
- fast_write client, "\r\n".freeze
682
+ fast_write client, "\r\n".freeze
683
+ rescue ConnectionError
684
+ # noop, if we lost the socket we just won't send the early hints
685
+ end
665
686
  }
666
687
  end
667
688
 
@@ -687,7 +708,7 @@ module Puma
687
708
  to_add = {}
688
709
  end
689
710
 
690
- to_add[k.gsub(",", "_")] = v
711
+ to_add[k.tr(",", "_")] = v
691
712
  end
692
713
  end
693
714
 
@@ -861,11 +882,14 @@ module Puma
861
882
  end
862
883
 
863
884
  ensure
864
- uncork_socket client
885
+ begin
886
+ uncork_socket client
865
887
 
866
- body.close
867
- req.tempfile.unlink if req.tempfile
868
- res_body.close if res_body.respond_to? :close
888
+ body.close
889
+ req.tempfile.unlink if req.tempfile
890
+ ensure
891
+ res_body.close if res_body.respond_to? :close
892
+ end
869
893
 
870
894
  after_reply.each { |o| o.call }
871
895
  end
@@ -990,6 +1014,10 @@ module Puma
990
1014
  @events.debug "Drained #{count} additional connections."
991
1015
  end
992
1016
 
1017
+ if @status != :restart
1018
+ @binder.close
1019
+ end
1020
+
993
1021
  if @thread_pool
994
1022
  if timeout = @options[:force_shutdown_after]
995
1023
  @thread_pool.shutdown timeout.to_i
data/lib/puma/single.rb CHANGED
@@ -18,7 +18,7 @@ module Puma
18
18
  r = @server.running || 0
19
19
  t = @server.pool_capacity || 0
20
20
  m = @server.max_threads || 0
21
- %Q!{ "backlog": #{b}, "running": #{r}, "pool_capacity": #{t}, "max_threads": #{m} }!
21
+ %Q!{ "started_at": "#{@started_at.utc.iso8601}", "backlog": #{b}, "running": #{r}, "pool_capacity": #{t}, "max_threads": #{m} }!
22
22
  end
23
23
 
24
24
  def restart
@@ -26,7 +26,7 @@ module Puma
26
26
  end
27
27
 
28
28
  def stop
29
- @server.stop false
29
+ @server.stop(false) if @server
30
30
  end
31
31
 
32
32
  def halt
@@ -36,7 +36,7 @@ module Puma
36
36
  def stop_blocked
37
37
  log "- Gracefully stopping, waiting for requests to finish"
38
38
  @control.stop(true) if @control
39
- @server.stop(true)
39
+ @server.stop(true) if @server
40
40
  end
41
41
 
42
42
  def jruby_daemon?
File without changes
File without changes
@@ -87,8 +87,7 @@ module Puma
87
87
  @spawned += 1
88
88
 
89
89
  th = Thread.new(@spawned) do |spawned|
90
- # Thread name is new in Ruby 2.3
91
- Thread.current.name = 'puma %03i' % spawned if Thread.current.respond_to?(:name=)
90
+ Puma.set_thread_name 'threadpool %03i' % spawned
92
91
  todo = @todo
93
92
  block = @block
94
93
  mutex = @mutex
@@ -190,10 +189,13 @@ module Puma
190
189
  # request, it might not be added to the `@todo` array right away.
191
190
  # For example if a slow client has only sent a header, but not a body
192
191
  # then the `@todo` array would stay the same size as the reactor works
193
- # to try to buffer the request. In tha scenario the next call to this
192
+ # to try to buffer the request. In that scenario the next call to this
194
193
  # method would not block and another request would be added into the reactor
195
194
  # by the server. This would continue until a fully bufferend request
196
195
  # makes it through the reactor and can then be processed by the thread pool.
196
+ #
197
+ # Returns the current number of busy threads, or +nil+ if shutting down.
198
+ #
197
199
  def wait_until_not_full
198
200
  @mutex.synchronize do
199
201
  while true
@@ -203,7 +205,8 @@ module Puma
203
205
  # is work queued that cannot be handled by waiting
204
206
  # threads, then accept more work until we would
205
207
  # spin up the max number of threads.
206
- return if @todo.size - @waiting < @max - @spawned
208
+ busy_threads = @spawned - @waiting + @todo.size
209
+ return busy_threads if @max > busy_threads
207
210
 
208
211
  @not_full.wait @mutex
209
212
  end
@@ -240,10 +243,12 @@ module Puma
240
243
  end
241
244
  end
242
245
 
243
- class AutoTrim
244
- def initialize(pool, timeout)
246
+ class Automaton
247
+ def initialize(pool, timeout, thread_name, message)
245
248
  @pool = pool
246
249
  @timeout = timeout
250
+ @thread_name = thread_name
251
+ @message = message
247
252
  @running = false
248
253
  end
249
254
 
@@ -251,8 +256,9 @@ module Puma
251
256
  @running = true
252
257
 
253
258
  @thread = Thread.new do
259
+ Puma.set_thread_name @thread_name
254
260
  while @running
255
- @pool.trim
261
+ @pool.public_send(@message)
256
262
  sleep @timeout
257
263
  end
258
264
  end
@@ -265,36 +271,12 @@ module Puma
265
271
  end
266
272
 
267
273
  def auto_trim!(timeout=30)
268
- @auto_trim = AutoTrim.new(self, timeout)
274
+ @auto_trim = Automaton.new(self, timeout, "threadpool trimmer", :trim)
269
275
  @auto_trim.start!
270
276
  end
271
277
 
272
- class Reaper
273
- def initialize(pool, timeout)
274
- @pool = pool
275
- @timeout = timeout
276
- @running = false
277
- end
278
-
279
- def start!
280
- @running = true
281
-
282
- @thread = Thread.new do
283
- while @running
284
- @pool.reap
285
- sleep @timeout
286
- end
287
- end
288
- end
289
-
290
- def stop
291
- @running = false
292
- @thread.wakeup
293
- end
294
- end
295
-
296
278
  def auto_reap!(timeout=5)
297
- @reaper = Reaper.new(self, timeout)
279
+ @reaper = Automaton.new(self, timeout, "threadpool reaper", :reap)
298
280
  @reaper.start!
299
281
  end
300
282
 
data/lib/puma/util.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  # frozen_string_literal: true
2
- major, minor, patch = RUBY_VERSION.split('.').map { |v| v.to_i }
3
2
 
4
- if major == 1 && minor == 9 && patch == 3 && RUBY_PATCHLEVEL < 125
5
- require 'puma/rack/backports/uri/common_193'
6
- else
7
- require 'uri/common'
8
- end
3
+ require 'uri/common'
9
4
 
10
5
  module Puma
11
6
  module Util
data/lib/puma.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Standard libraries
2
4
  require 'socket'
3
5
  require 'tempfile'
@@ -20,4 +22,10 @@ module Puma
20
22
  def self.stats
21
23
  @get_stats.stats
22
24
  end
25
+
26
+ # Thread name is new in Ruby 2.3
27
+ def self.set_thread_name(name)
28
+ return unless Thread.current.respond_to?(:name=)
29
+ Thread.current.name = "puma #{name}"
30
+ end
23
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/handler'
2
4
 
3
5
  module Rack
@@ -59,8 +61,6 @@ module Rack
59
61
  conf
60
62
  end
61
63
 
62
-
63
-
64
64
  def self.run(app, options = {})
65
65
  conf = self.config(app, options)
66
66
 
@@ -86,7 +86,7 @@ module Rack
86
86
  "Verbose" => "Don't report each request (default: false)"
87
87
  }
88
88
  end
89
- private
89
+
90
90
  def self.set_host_port_to_config(host, port, config)
91
91
  config.clear_binds! if host || port
92
92
 
@@ -0,0 +1,16 @@
1
+ # Use this Dockerfile to create minimal reproductions of issues
2
+
3
+ FROM ruby:2.6
4
+
5
+ # throw errors if Gemfile has been modified since Gemfile.lock
6
+ RUN bundle config --global frozen 1
7
+
8
+ WORKDIR /usr/src/app
9
+
10
+ COPY . .
11
+ RUN gem install bundler
12
+ RUN bundle install
13
+ RUN bundle exec rake compile
14
+
15
+ EXPOSE 9292
16
+ CMD bundle exec bin/puma test/rackup/hello.ru
File without changes
File without changes
@@ -47,11 +47,11 @@ do_start_one() {
47
47
  PIDFILE=$1/tmp/puma/pid
48
48
  if [ -e $PIDFILE ]; then
49
49
  PID=`cat $PIDFILE`
50
- # If the puma isn't running, run it, otherwise restart it.
50
+ # If the puma is running, restart it, otherwise run it.
51
51
  if ps -p $PID > /dev/null; then
52
- do_start_one_do $1
53
- else
54
52
  do_restart_one $1
53
+ else
54
+ do_start_one_do $1
55
55
  fi
56
56
  else
57
57
  do_start_one_do $1
@@ -106,8 +106,6 @@ do_stop_one() {
106
106
  if [ -e $PIDFILE ]; then
107
107
  PID=`cat $PIDFILE`
108
108
  if ps -p $PID > /dev/null; then
109
- log_daemon_msg "---> Puma $1 isn't running."
110
- else
111
109
  log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
112
110
  if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
113
111
  cd $1 && bundle exec pumactl --state $STATEFILE stop
@@ -116,6 +114,8 @@ do_stop_one() {
116
114
  fi
117
115
  # Many daemons don't delete their pidfiles when they exit.
118
116
  rm -f $PIDFILE $STATEFILE
117
+ else
118
+ log_daemon_msg "---> Puma $1 isn't running."
119
119
  fi
120
120
  else
121
121
  log_daemon_msg "---> No puma here..."
@@ -398,7 +398,7 @@ case "$1" in
398
398
  ;;
399
399
  remove)
400
400
  if [ "$#" -lt 2 ]; then
401
- echo "Please, specifiy the app's directory to remove."
401
+ echo "Please, specify the app's directory to remove."
402
402
  exit 1
403
403
  else
404
404
  do_remove $2
File without changes
File without changes
File without changes
File without changes
File without changes
data/tools/trickletest.rb CHANGED
@@ -38,7 +38,6 @@ ARGV[1].to_i.times do
38
38
  do_test(st, size)
39
39
  end
40
40
 
41
- t.abort_on_exception = true
42
41
  threads << t
43
42
  end
44
43
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.12.6
4
+ version: 4.3.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-19 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 1980-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nio4r
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
13
27
  description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
14
28
  for Ruby/Rack applications. Puma is intended for use in both development and production
15
29
  environments. It's great for highly concurrent Ruby implementations such as Rubinius
@@ -39,6 +53,7 @@ files:
39
53
  - docs/restart.md
40
54
  - docs/signals.md
41
55
  - docs/systemd.md
56
+ - docs/tcp_mode.md
42
57
  - ext/puma_http11/PumaHttp11Service.java
43
58
  - ext/puma_http11/ext_help.h
44
59
  - ext/puma_http11/extconf.rb
@@ -51,6 +66,7 @@ files:
51
66
  - ext/puma_http11/mini_ssl.c
52
67
  - ext/puma_http11/org/jruby/puma/Http11.java
53
68
  - ext/puma_http11/org/jruby/puma/Http11Parser.java
69
+ - ext/puma_http11/org/jruby/puma/IOBuffer.java
54
70
  - ext/puma_http11/org/jruby/puma/MiniSSL.java
55
71
  - ext/puma_http11/puma_http11.c
56
72
  - lib/puma.rb
@@ -61,25 +77,20 @@ files:
61
77
  - lib/puma/client.rb
62
78
  - lib/puma/cluster.rb
63
79
  - lib/puma/commonlogger.rb
64
- - lib/puma/compat.rb
65
80
  - lib/puma/configuration.rb
66
81
  - lib/puma/const.rb
67
82
  - lib/puma/control_cli.rb
68
- - lib/puma/convenient.rb
69
- - lib/puma/daemon_ext.rb
70
- - lib/puma/delegation.rb
71
83
  - lib/puma/detect.rb
72
84
  - lib/puma/dsl.rb
73
85
  - lib/puma/events.rb
74
86
  - lib/puma/io_buffer.rb
75
- - lib/puma/java_io_buffer.rb
76
87
  - lib/puma/jruby_restart.rb
77
88
  - lib/puma/launcher.rb
78
89
  - lib/puma/minissl.rb
90
+ - lib/puma/minissl/context_builder.rb
79
91
  - lib/puma/null_io.rb
80
92
  - lib/puma/plugin.rb
81
93
  - lib/puma/plugin/tmp_restart.rb
82
- - lib/puma/rack/backports/uri/common_193.rb
83
94
  - lib/puma/rack/builder.rb
84
95
  - lib/puma/rack/urlmap.rb
85
96
  - lib/puma/rack_default.rb
@@ -92,6 +103,7 @@ files:
92
103
  - lib/puma/thread_pool.rb
93
104
  - lib/puma/util.rb
94
105
  - lib/rack/handler/puma.rb
106
+ - tools/docker/Dockerfile
95
107
  - tools/jungle/README.md
96
108
  - tools/jungle/init.d/README.md
97
109
  - tools/jungle/init.d/puma
@@ -108,7 +120,8 @@ licenses:
108
120
  - BSD-3-Clause
109
121
  metadata:
110
122
  msys2_mingw_dependencies: openssl
111
- post_install_message:
123
+ changelog_uri: https://github.com/puma/puma/blob/master/History.md
124
+ post_install_message:
112
125
  rdoc_options: []
113
126
  require_paths:
114
127
  - lib
@@ -123,8 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
136
  - !ruby/object:Gem::Version
124
137
  version: '0'
125
138
  requirements: []
126
- rubygems_version: 3.0.3
127
- signing_key:
139
+ rubygems_version: 3.2.26
140
+ signing_key:
128
141
  specification_version: 4
129
142
  summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
130
143
  Ruby/Rack applications