puma 6.4.3-java → 6.6.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,14 +15,14 @@ module Puma
15
15
 
16
16
  LOG_QUEUE = Queue.new
17
17
 
18
- def initialize(ioerr)
18
+ def initialize(ioerr, env: ENV)
19
19
  @ioerr = ioerr
20
20
 
21
- @debug = ENV.key? 'PUMA_DEBUG'
21
+ @debug = env.key?('PUMA_DEBUG')
22
22
  end
23
23
 
24
- def self.stdio
25
- new $stderr
24
+ def self.stdio(env: ENV)
25
+ new($stderr, env: env)
26
26
  end
27
27
 
28
28
  # Print occurred error details.
@@ -6,22 +6,6 @@ module Puma
6
6
  module JRubyRestart
7
7
  extend FFI::Library
8
8
  ffi_lib 'c'
9
-
10
- attach_function :execlp, [:string, :varargs], :int
11
9
  attach_function :chdir, [:string], :int
12
- attach_function :fork, [], :int
13
- attach_function :exit, [:int], :void
14
- attach_function :setsid, [], :int
15
-
16
- def self.chdir_exec(dir, argv)
17
- chdir(dir)
18
- cmd = argv.first
19
- argv = ([:string] * argv.size).zip(argv)
20
- argv.flatten!
21
- argv << :string
22
- argv << nil
23
- execlp(cmd, *argv)
24
- raise SystemCallError.new(FFI.errno)
25
- end
26
10
  end
27
11
  end
data/lib/puma/launcher.rb CHANGED
@@ -46,6 +46,8 @@ module Puma
46
46
  @original_argv = @argv.dup
47
47
  @config = conf
48
48
 
49
+ env = launcher_args.delete(:env) || ENV
50
+
49
51
  @config.options[:log_writer] = @log_writer
50
52
 
51
53
  # Advertise the Configuration
@@ -62,7 +64,7 @@ module Puma
62
64
  # Load the systemd integration if we detect systemd's NOTIFY_SOCKET.
63
65
  # Skip this on JRuby though, because it is incompatible with the systemd
64
66
  # integration due to https://github.com/jruby/jruby/issues/6504
65
- if ENV["NOTIFY_SOCKET"] && !Puma.jruby?
67
+ if ENV["NOTIFY_SOCKET"] && !Puma.jruby? && !ENV["PUMA_SKIP_SYSTEMD"]
66
68
  @config.plugins.create('systemd')
67
69
  end
68
70
 
@@ -105,7 +107,7 @@ module Puma
105
107
 
106
108
  @status = :run
107
109
 
108
- log_config if ENV['PUMA_LOG_CONFIG']
110
+ log_config if env['PUMA_LOG_CONFIG']
109
111
  end
110
112
 
111
113
  attr_reader :binder, :log_writer, :events, :config, :options, :restart_dir
@@ -165,6 +167,13 @@ module Puma
165
167
  log "* phased-restart called but not available, restarting normally."
166
168
  return restart
167
169
  end
170
+
171
+ if @options.file_options[:tag].nil?
172
+ dir = File.realdirpath(@restart_dir)
173
+ @options[:tag] = File.basename(dir)
174
+ set_process_title
175
+ end
176
+
168
177
  true
169
178
  end
170
179
 
@@ -287,7 +296,9 @@ module Puma
287
296
  close_binder_listeners
288
297
 
289
298
  require_relative 'jruby_restart'
290
- JRubyRestart.chdir_exec(@restart_dir, restart_args)
299
+ argv = restart_args
300
+ JRubyRestart.chdir(@restart_dir)
301
+ Kernel.exec(*argv)
291
302
  elsif Puma.windows?
292
303
  close_binder_listeners
293
304
 
@@ -408,12 +419,14 @@ module Puma
408
419
  end
409
420
 
410
421
  def setup_signals
411
- begin
412
- Signal.trap "SIGUSR2" do
413
- restart
422
+ unless ENV["PUMA_SKIP_SIGUSR2"]
423
+ begin
424
+ Signal.trap "SIGUSR2" do
425
+ restart
426
+ end
427
+ rescue Exception
428
+ log "*** SIGUSR2 not implemented, signal based restart unavailable!"
414
429
  end
415
- rescue Exception
416
- log "*** SIGUSR2 not implemented, signal based restart unavailable!"
417
430
  end
418
431
 
419
432
  unless Puma.jruby?
@@ -31,31 +31,31 @@ module Puma
31
31
  attr_accessor :formatter, :custom_logger
32
32
 
33
33
  # Create a LogWriter that prints to +stdout+ and +stderr+.
34
- def initialize(stdout, stderr)
34
+ def initialize(stdout, stderr, env: ENV)
35
35
  @formatter = DefaultFormatter.new
36
36
  @custom_logger = nil
37
37
  @stdout = stdout
38
38
  @stderr = stderr
39
39
 
40
- @debug = ENV.key?('PUMA_DEBUG')
41
- @error_logger = ErrorLogger.new(@stderr)
40
+ @debug = env.key?('PUMA_DEBUG')
41
+ @error_logger = ErrorLogger.new(@stderr, env: env)
42
42
  end
43
43
 
44
44
  DEFAULT = new(STDOUT, STDERR)
45
45
 
46
46
  # Returns an LogWriter object which writes its status to
47
47
  # two StringIO objects.
48
- def self.strings
49
- LogWriter.new(StringIO.new, StringIO.new)
48
+ def self.strings(env: ENV)
49
+ LogWriter.new(StringIO.new, StringIO.new, env: env)
50
50
  end
51
51
 
52
- def self.stdio
53
- LogWriter.new($stdout, $stderr)
52
+ def self.stdio(env: ENV)
53
+ LogWriter.new($stdout, $stderr, env: env)
54
54
  end
55
55
 
56
- def self.null
56
+ def self.null(env: ENV)
57
57
  n = NullIO.new
58
- LogWriter.new(n, n)
58
+ LogWriter.new(n, n, env: env)
59
59
  end
60
60
 
61
61
  # Write +str+ to +@stdout+
@@ -57,6 +57,7 @@ module Puma
57
57
 
58
58
  ctx.ca = params['ca'] if params['ca']
59
59
  ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
60
+ ctx.ssl_ciphersuites = params['ssl_ciphersuites'] if params['ssl_ciphersuites'] && HAS_TLS1_3
60
61
 
61
62
  ctx.reuse = params['reuse'] if params['reuse']
62
63
  end
data/lib/puma/minissl.rb CHANGED
@@ -289,6 +289,7 @@ module Puma
289
289
  attr_reader :cert_pem
290
290
  attr_reader :key_pem
291
291
  attr_accessor :ssl_cipher_filter
292
+ attr_accessor :ssl_ciphersuites
292
293
  attr_accessor :verification_flags
293
294
 
294
295
  attr_reader :reuse, :reuse_cache_size, :reuse_timeout
data/lib/puma/null_io.rb CHANGED
@@ -16,6 +16,10 @@ module Puma
16
16
  def each
17
17
  end
18
18
 
19
+ def pos
20
+ 0
21
+ end
22
+
19
23
  # Mimics IO#read with no data.
20
24
  #
21
25
  def read(length = nil, buffer = nil)
@@ -39,6 +43,11 @@ module Puma
39
43
  def rewind
40
44
  end
41
45
 
46
+ def seek(pos, whence = 0)
47
+ raise ArgumentError, "negative length #{pos} given" if pos.negative?
48
+ 0
49
+ end
50
+
42
51
  def close
43
52
  end
44
53
 
@@ -71,5 +80,22 @@ module Puma
71
80
  def closed?
72
81
  false
73
82
  end
83
+
84
+ def set_encoding(enc)
85
+ self
86
+ end
87
+
88
+ # per rack spec
89
+ def external_encoding
90
+ Encoding::ASCII_8BIT
91
+ end
92
+
93
+ def binmode
94
+ self
95
+ end
96
+
97
+ def binmode?
98
+ true
99
+ end
74
100
  end
75
101
  end
Binary file
data/lib/puma/request.rb CHANGED
@@ -53,7 +53,6 @@ module Puma
53
53
  socket = client.io # io may be a MiniSSL::Socket
54
54
  app_body = nil
55
55
 
56
-
57
56
  return false if closed_socket?(socket)
58
57
 
59
58
  if client.http_content_length_limit_exceeded
@@ -135,7 +134,7 @@ module Puma
135
134
  io_buffer.reset
136
135
  uncork_socket client.io
137
136
  app_body.close if app_body.respond_to? :close
138
- client.tempfile&.unlink
137
+ client&.tempfile_close
139
138
  after_reply = env[RACK_AFTER_REPLY] || []
140
139
  begin
141
140
  after_reply.each { |o| o.call }
@@ -165,9 +164,14 @@ module Puma
165
164
  # if the server is at capacity and the listener has a new connection ready.
166
165
  # This allows Puma to service connections fairly when the number
167
166
  # of concurrent connections exceeds the size of the threadpool.
168
- force_keep_alive = requests < @max_fast_inline ||
167
+ force_keep_alive = if @enable_keep_alives
168
+ requests < @max_fast_inline ||
169
169
  @thread_pool.busy_threads < @max_threads ||
170
170
  !client.listener.to_io.wait_readable(0)
171
+ else
172
+ # Always set force_keep_alive to false if the server has keep-alives not enabled.
173
+ false
174
+ end
171
175
 
172
176
  resp_info = str_headers(env, status, headers, res_body, io_buffer, force_keep_alive)
173
177
 
data/lib/puma/runner.rb CHANGED
@@ -8,6 +8,9 @@ module Puma
8
8
  # serve requests. This class spawns a new instance of `Puma::Server` via
9
9
  # a call to `start_server`.
10
10
  class Runner
11
+
12
+ include ::Puma::Const::PipeRequest
13
+
11
14
  def initialize(launcher)
12
15
  @launcher = launcher
13
16
  @log_writer = launcher.log_writer
@@ -27,7 +30,7 @@ module Puma
27
30
  def wakeup!
28
31
  return unless @wakeup
29
32
 
30
- @wakeup.write "!" unless @wakeup.closed?
33
+ @wakeup.write PIPE_WAKEUP unless @wakeup.closed?
31
34
 
32
35
  rescue SystemCallError, IOError
33
36
  Puma::Util.purge_interrupt_queue
@@ -91,7 +94,10 @@ module Puma
91
94
  end
92
95
 
93
96
  # @!attribute [r] ruby_engine
97
+ # @deprecated Use `RUBY_DESCRIPTION` instead
94
98
  def ruby_engine
99
+ warn "Puma::Runner#ruby_engine is deprecated; use RUBY_DESCRIPTION instead. It will be removed in puma v7."
100
+
95
101
  if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
96
102
  "ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
97
103
  else
@@ -109,7 +115,8 @@ module Puma
109
115
  environment = @options[:environment]
110
116
 
111
117
  log "Puma starting in #{mode} mode..."
112
- log "* Puma version: #{Puma::Const::PUMA_VERSION} (#{ruby_engine}) (\"#{Puma::Const::CODE_NAME}\")"
118
+ log "* Puma version: #{Puma::Const::PUMA_VERSION} (\"#{Puma::Const::CODE_NAME}\")"
119
+ log "* Ruby version: #{RUBY_DESCRIPTION}"
113
120
  log "* Min threads: #{min_t}"
114
121
  log "* Max threads: #{max_t}"
115
122
  log "* Environment: #{environment}"
@@ -137,10 +137,7 @@ module Puma
137
137
  ENV.delete("NOTIFY_SOCKET") if unset_env
138
138
 
139
139
  begin
140
- Addrinfo.unix(sock, :DGRAM).connect do |s|
141
- s.close_on_exec = true
142
- s.write(state)
143
- end
140
+ Addrinfo.unix(sock, :DGRAM).connect { |s| s.write state }
144
141
  rescue StandardError => e
145
142
  raise NotifyError, "#{e.class}: #{e.message}", e.backtrace
146
143
  end
data/lib/puma/server.rb CHANGED
@@ -18,6 +18,9 @@ require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
18
18
 
19
19
  module Puma
20
20
 
21
+ # This method was private on Ruby 2.4 but became public on Ruby 2.5+:
22
+ Thread.send(:attr_accessor, :puma_server)
23
+
21
24
  # The HTTP Server itself. Serves out a single Rack app.
22
25
  #
23
26
  # This class is used by the `Puma::Single` and `Puma::Cluster` classes
@@ -32,6 +35,7 @@ module Puma
32
35
  include Puma::Const
33
36
  include Request
34
37
 
38
+ attr_reader :options
35
39
  attr_reader :thread
36
40
  attr_reader :log_writer
37
41
  attr_reader :events
@@ -46,7 +50,6 @@ module Puma
46
50
  attr_accessor :app
47
51
  attr_accessor :binder
48
52
 
49
- THREAD_LOCAL_KEY = :puma_server
50
53
 
51
54
  # Create a server for the rack app +app+.
52
55
  #
@@ -92,6 +95,7 @@ module Puma
92
95
  @max_threads = @options[:max_threads]
93
96
  @queue_requests = @options[:queue_requests]
94
97
  @max_fast_inline = @options[:max_fast_inline]
98
+ @enable_keep_alives = @options[:enable_keep_alives]
95
99
  @io_selector_backend = @options[:io_selector_backend]
96
100
  @http_content_length_limit = @options[:http_content_length_limit]
97
101
 
@@ -130,7 +134,7 @@ module Puma
130
134
  class << self
131
135
  # @!attribute [r] current
132
136
  def current
133
- Thread.current[THREAD_LOCAL_KEY]
137
+ Thread.current.puma_server
134
138
  end
135
139
 
136
140
  # :nodoc:
@@ -229,6 +233,11 @@ module Puma
229
233
  @thread_pool&.pool_capacity
230
234
  end
231
235
 
236
+ # @!attribute [r] busy_threads
237
+ def busy_threads
238
+ @thread_pool&.busy_threads
239
+ end
240
+
232
241
  # Runs the server.
233
242
  #
234
243
  # If +background+ is true (the default) then a thread is spun
@@ -242,16 +251,15 @@ module Puma
242
251
 
243
252
  @status = :run
244
253
 
245
- @thread_pool = ThreadPool.new(thread_name, @options) { |client| process_client client }
254
+ @thread_pool = ThreadPool.new(thread_name, options) { |client| process_client client }
246
255
 
247
256
  if @queue_requests
248
257
  @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
249
258
  @reactor.run
250
259
  end
251
260
 
252
-
253
- @thread_pool.auto_reap! if @options[:reaping_time]
254
- @thread_pool.auto_trim! if @options[:auto_trim_time]
261
+ @thread_pool.auto_reap! if options[:reaping_time]
262
+ @thread_pool.auto_trim! if @min_threads != @max_threads && options[:auto_trim_time]
255
263
 
256
264
  @check, @notify = Puma::Util.pipe unless @notify
257
265
 
@@ -315,15 +323,15 @@ module Puma
315
323
  sockets = [check] + @binder.ios
316
324
  pool = @thread_pool
317
325
  queue_requests = @queue_requests
318
- drain = @options[:drain_on_shutdown] ? 0 : nil
326
+ drain = options[:drain_on_shutdown] ? 0 : nil
319
327
 
320
- addr_send_name, addr_value = case @options[:remote_address]
328
+ addr_send_name, addr_value = case options[:remote_address]
321
329
  when :value
322
- [:peerip=, @options[:remote_address_value]]
330
+ [:peerip=, options[:remote_address_value]]
323
331
  when :header
324
- [:remote_addr_header=, @options[:remote_address_header]]
332
+ [:remote_addr_header=, options[:remote_address_header]]
325
333
  when :proxy_protocol
326
- [:expect_proxy_proto=, @options[:remote_address_proxy_protocol]]
334
+ [:expect_proxy_proto=, options[:remote_address_proxy_protocol]]
327
335
  else
328
336
  [nil, nil]
329
337
  end
@@ -336,7 +344,7 @@ module Puma
336
344
  @idle_timeout_reached = true
337
345
 
338
346
  if @clustered
339
- @worker_write << "i#{Process.pid}\n" rescue nil
347
+ @worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
340
348
  next
341
349
  else
342
350
  @log_writer.log "- Idle timeout reached"
@@ -349,7 +357,7 @@ module Puma
349
357
 
350
358
  if @idle_timeout_reached && @clustered
351
359
  @idle_timeout_reached = false
352
- @worker_write << "i#{Process.pid}\n" rescue nil
360
+ @worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
353
361
  end
354
362
 
355
363
  ios.first.each do |sock|
@@ -357,7 +365,7 @@ module Puma
357
365
  break if handle_check
358
366
  else
359
367
  pool.wait_until_not_full
360
- pool.wait_for_less_busy_worker(@options[:wait_for_less_busy_worker])
368
+ pool.wait_for_less_busy_worker(options[:wait_for_less_busy_worker]) if @clustered
361
369
 
362
370
  io = begin
363
371
  sock.accept_nonblock
@@ -437,9 +445,9 @@ module Puma
437
445
  # Return true if one or more requests were processed.
438
446
  def process_client(client)
439
447
  # Advertise this server into the thread
440
- Thread.current[THREAD_LOCAL_KEY] = self
448
+ Thread.current.puma_server = self
441
449
 
442
- clean_thread_locals = @options[:clean_thread_locals]
450
+ clean_thread_locals = options[:clean_thread_locals]
443
451
  close_socket = true
444
452
 
445
453
  requests = 0
@@ -548,7 +556,7 @@ module Puma
548
556
  # A fallback rack response if +@app+ raises as exception.
549
557
  #
550
558
  def lowlevel_error(e, env, status=500)
551
- if handler = @options[:lowlevel_error_handler]
559
+ if handler = options[:lowlevel_error_handler]
552
560
  if handler.arity == 1
553
561
  return handler.call(e)
554
562
  elsif handler.arity == 2
@@ -569,14 +577,13 @@ module Puma
569
577
  def response_to_error(client, requests, err, status_code)
570
578
  status, headers, res_body = lowlevel_error(err, client.env, status_code)
571
579
  prepare_response(status, headers, res_body, requests, client)
572
- client.write_error(status_code)
573
580
  end
574
581
  private :response_to_error
575
582
 
576
583
  # Wait for all outstanding requests to finish.
577
584
  #
578
585
  def graceful_shutdown
579
- if @options[:shutdown_debug]
586
+ if options[:shutdown_debug]
580
587
  threads = Thread.list
581
588
  total = threads.size
582
589
 
@@ -596,7 +603,7 @@ module Puma
596
603
  end
597
604
 
598
605
  if @thread_pool
599
- if timeout = @options[:force_shutdown_after]
606
+ if timeout = options[:force_shutdown_after]
600
607
  @thread_pool.shutdown timeout.to_f
601
608
  else
602
609
  @thread_pool.shutdown
@@ -643,13 +650,17 @@ module Puma
643
650
 
644
651
  # List of methods invoked by #stats.
645
652
  # @version 5.0.0
646
- STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count].freeze
653
+ STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count, :busy_threads].freeze
647
654
 
648
655
  # Returns a hash of stats about the running server for reporting purposes.
649
656
  # @version 5.0.0
650
657
  # @!attribute [r] stats
658
+ # @return [Hash] hash containing stat info from `Server` and `ThreadPool`
651
659
  def stats
652
- STAT_METHODS.map {|name| [name, send(name) || 0]}.to_h
660
+ stats = @thread_pool&.stats || {}
661
+ stats[:max_threads] = @max_threads
662
+ stats[:requests_count] = @requests_count
663
+ stats
653
664
  end
654
665
 
655
666
  # below are 'delegations' to binder
@@ -85,6 +85,18 @@ module Puma
85
85
  end
86
86
  end
87
87
 
88
+ # generate stats hash so as not to perform multiple locks
89
+ # @return [Hash] hash containing stat info from ThreadPool
90
+ def stats
91
+ with_mutex do
92
+ { backlog: @todo.size,
93
+ running: @spawned,
94
+ pool_capacity: @waiting + (@max - @spawned),
95
+ busy_threads: @spawned - @waiting + @todo.size
96
+ }
97
+ end
98
+ end
99
+
88
100
  # How many objects have yet to be processed by the pool?
89
101
  #
90
102
  def backlog
@@ -358,12 +370,12 @@ module Puma
358
370
  end
359
371
 
360
372
  def auto_trim!(timeout=@auto_trim_time)
361
- @auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
373
+ @auto_trim = Automaton.new(self, timeout, "#{@name} tp trim", :trim)
362
374
  @auto_trim.start!
363
375
  end
364
376
 
365
377
  def auto_reap!(timeout=@reaping_time)
366
- @reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
378
+ @reaper = Automaton.new(self, timeout, "#{@name} tp reap", :reap)
367
379
  @reaper.start!
368
380
  end
369
381
 
data/lib/puma/util.rb CHANGED
@@ -11,7 +11,7 @@ module Puma
11
11
  end
12
12
 
13
13
  # An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632,
14
- # which currently effects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1
14
+ # which currently affects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1
15
15
  # Additional context: https://github.com/puma/puma/pull/1345
16
16
  def purge_interrupt_queue
17
17
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This module is used as an 'include' file in code at bottom of file
4
3
  module Puma
4
+
5
+ # This module is used as an 'include' file in code at bottom of file. It loads
6
+ # into either `Rackup::Handler::Puma` or `Rack::Handler::Puma`.
7
+
5
8
  module RackHandler
6
9
  DEFAULT_OPTIONS = {
7
10
  :Verbose => false,
@@ -93,9 +96,9 @@ module Puma
93
96
  def set_host_port_to_config(host, port, config)
94
97
  config.clear_binds! if host || port
95
98
 
96
- if host && (host[0,1] == '.' || host[0,1] == '/')
99
+ if host&.start_with? '.', '/', '@'
97
100
  config.bind "unix://#{host}"
98
- elsif host && host =~ /^ssl:\/\//
101
+ elsif host&.start_with? 'ssl://'
99
102
  uri = URI.parse(host)
100
103
  uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
101
104
  config.bind uri.to_s
@@ -115,7 +118,7 @@ module Puma
115
118
  end
116
119
 
117
120
  # rackup was removed in Rack 3, it is now a separate gem
118
- if Object.const_defined? :Rackup
121
+ if Object.const_defined?(:Rackup) && ::Rackup.const_defined?(:Handler)
119
122
  module Rackup
120
123
  module Handler
121
124
  module Puma
@@ -127,7 +130,7 @@ if Object.const_defined? :Rackup
127
130
  end
128
131
  end
129
132
  else
130
- do_register = Object.const_defined?(:Rack) && Rack.release < '3'
133
+ do_register = Object.const_defined?(:Rack) && ::Rack.release < '3'
131
134
  module Rack
132
135
  module Handler
133
136
  module Puma
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.4.3
4
+ version: 6.6.0
5
5
  platform: java
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-19 00:00:00.000000000 Z
11
+ date: 2025-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -24,10 +24,11 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
- description: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server
28
- for Ruby/Rack applications. Puma is intended for use in both development and production
29
- environments. It's great for highly parallel Ruby implementations such as Rubinius
30
- and JRuby as well as as providing process worker support to support CRuby well.
27
+ description: |
28
+ Puma is a simple, fast, multi-threaded, and highly parallel HTTP 1.1 server
29
+ for Ruby/Rack applications. Puma is intended for use in both development and
30
+ production environments. It's great for highly parallel Ruby implementations such as
31
+ JRuby and TruffleRuby as well as as providing process worker support to support CRuby well.
31
32
  email:
32
33
  - evan@phx.io
33
34
  executables:
@@ -49,6 +50,7 @@ files:
49
50
  - docs/images/puma-connection-flow-no-reactor.png
50
51
  - docs/images/puma-connection-flow.png
51
52
  - docs/images/puma-general-arch.png
53
+ - docs/java_options.md
52
54
  - docs/jungle/README.md
53
55
  - docs/jungle/rc.d/README.md
54
56
  - docs/jungle/rc.d/puma
@@ -148,6 +150,5 @@ requirements: []
148
150
  rubygems_version: 3.3.26
149
151
  signing_key:
150
152
  specification_version: 4
151
- summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
152
- Ruby/Rack applications
153
+ summary: A Ruby/Rack web server built for parallelism.
153
154
  test_files: []