puma 6.0.0 → 6.2.0

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.

data/lib/puma/server.rb CHANGED
@@ -11,7 +11,6 @@ require_relative 'reactor'
11
11
  require_relative 'client'
12
12
  require_relative 'binder'
13
13
  require_relative 'util'
14
- require_relative 'io_buffer'
15
14
  require_relative 'request'
16
15
 
17
16
  require 'socket'
@@ -96,6 +95,7 @@ module Puma
96
95
  @queue_requests = @options[:queue_requests]
97
96
  @max_fast_inline = @options[:max_fast_inline]
98
97
  @io_selector_backend = @options[:io_selector_backend]
98
+ @http_content_length_limit = @options[:http_content_length_limit]
99
99
 
100
100
  temp = !!(@options[:environment] =~ /\A(development|test)\z/)
101
101
  @leak_stack_on_error = @options[:environment] ? temp : true
@@ -230,7 +230,7 @@ module Puma
230
230
 
231
231
  @status = :run
232
232
 
233
- @thread_pool = ThreadPool.new(thread_name, @options) { |a, b| process_client a, b }
233
+ @thread_pool = ThreadPool.new(thread_name, @options) { |client| process_client client }
234
234
 
235
235
  if @queue_requests
236
236
  @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
@@ -335,6 +335,7 @@ module Puma
335
335
  drain += 1 if shutting_down?
336
336
  pool << Client.new(io, @binder.env(sock)).tap { |c|
337
337
  c.listener = sock
338
+ c.http_content_length_limit = @http_content_length_limit
338
339
  c.send(addr_send_name, addr_value) if addr_value
339
340
  }
340
341
  end
@@ -401,7 +402,7 @@ module Puma
401
402
  # returning.
402
403
  #
403
404
  # Return true if one or more requests were processed.
404
- def process_client(client, buffer)
405
+ def process_client(client)
405
406
  # Advertise this server into the thread
406
407
  Thread.current[ThreadLocalKey] = self
407
408
 
@@ -427,15 +428,13 @@ module Puma
427
428
 
428
429
  while true
429
430
  @requests_count += 1
430
- case handle_request(client, buffer, requests + 1)
431
+ case handle_request(client, requests + 1)
431
432
  when false
432
433
  break
433
434
  when :async
434
435
  close_socket = false
435
436
  break
436
437
  when true
437
- buffer.reset
438
-
439
438
  ThreadPool.clean_thread_locals if clean_thread_locals
440
439
 
441
440
  requests += 1
@@ -469,7 +468,7 @@ module Puma
469
468
  # The ensure tries to close +client+ down
470
469
  requests > 0
471
470
  ensure
472
- buffer.reset
471
+ client.io_buffer.reset
473
472
 
474
473
  begin
475
474
  client.close if close_socket
data/lib/puma/single.rb CHANGED
@@ -16,7 +16,7 @@ module Puma
16
16
  # @!attribute [r] stats
17
17
  def stats
18
18
  {
19
- started_at: @started_at.utc.iso8601
19
+ started_at: utc_iso8601(@started_at)
20
20
  }.merge(@server.stats).merge(super)
21
21
  end
22
22
 
@@ -57,6 +57,8 @@ module Puma
57
57
 
58
58
  @events.fire_on_booted!
59
59
 
60
+ debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug?
61
+
60
62
  begin
61
63
  server_thread.join
62
64
  rescue Interrupt
@@ -45,7 +45,6 @@ module Puma
45
45
  @min = Integer(options[:min_threads])
46
46
  @max = Integer(options[:max_threads])
47
47
  @block = block
48
- @extra = [::Puma::IOBuffer]
49
48
  @out_of_band = options[:out_of_band]
50
49
  @clean_thread_locals = options[:clean_thread_locals]
51
50
  @reaping_time = options[:reaping_time]
@@ -112,8 +111,6 @@ module Puma
112
111
  not_empty = @not_empty
113
112
  not_full = @not_full
114
113
 
115
- extra = @extra.map { |i| i.new }
116
-
117
114
  while true
118
115
  work = nil
119
116
 
@@ -147,7 +144,7 @@ module Puma
147
144
  end
148
145
 
149
146
  begin
150
- @out_of_band_pending = true if block.call(work, *extra)
147
+ @out_of_band_pending = true if block.call(work)
151
148
  rescue Exception => e
152
149
  STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
153
150
  end
data/lib/puma.rb CHANGED
@@ -3,8 +3,6 @@
3
3
  # Standard libraries
4
4
  require 'socket'
5
5
  require 'tempfile'
6
- require 'time'
7
- require 'etc'
8
6
  require 'uri'
9
7
  require 'stringio'
10
8
 
@@ -28,7 +26,7 @@ module Puma
28
26
  # not in minissl.rb
29
27
  HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
30
28
 
31
- HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
29
+ HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
32
30
 
33
31
  if HAS_SSL
34
32
  require_relative 'puma/minissl'
@@ -1,114 +1,137 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack/handler'
4
-
5
- module Rack
6
- module Handler
7
- module Puma
8
- DEFAULT_OPTIONS = {
9
- :Verbose => false,
10
- :Silent => false
11
- }
12
-
13
- def self.config(app, options = {})
14
- require_relative '../../puma'
15
- require_relative '../../puma/configuration'
16
- require_relative '../../puma/log_writer'
17
- require_relative '../../puma/launcher'
18
-
19
- default_options = DEFAULT_OPTIONS.dup
20
-
21
- # Libraries pass in values such as :Port and there is no way to determine
22
- # if it is a default provided by the library or a special value provided
23
- # by the user. A special key `user_supplied_options` can be passed. This
24
- # contains an array of all explicitly defined user options. We then
25
- # know that all other values are defaults
26
- if user_supplied_options = options.delete(:user_supplied_options)
27
- (options.keys - user_supplied_options).each do |k|
28
- default_options[k] = options.delete(k)
29
- end
3
+ # This module is used as an 'include' file in code at bottom of file
4
+ module Puma
5
+ module RackHandler
6
+ DEFAULT_OPTIONS = {
7
+ :Verbose => false,
8
+ :Silent => false
9
+ }
10
+
11
+ def config(app, options = {})
12
+ require_relative '../../puma'
13
+ require_relative '../../puma/configuration'
14
+ require_relative '../../puma/log_writer'
15
+ require_relative '../../puma/launcher'
16
+
17
+ default_options = DEFAULT_OPTIONS.dup
18
+
19
+ # Libraries pass in values such as :Port and there is no way to determine
20
+ # if it is a default provided by the library or a special value provided
21
+ # by the user. A special key `user_supplied_options` can be passed. This
22
+ # contains an array of all explicitly defined user options. We then
23
+ # know that all other values are defaults
24
+ if user_supplied_options = options.delete(:user_supplied_options)
25
+ (options.keys - user_supplied_options).each do |k|
26
+ default_options[k] = options.delete(k)
30
27
  end
28
+ end
29
+
30
+ @events = options[:events] || ::Puma::Events.new
31
31
 
32
- conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
33
- if options.delete(:Verbose)
34
- require 'rack/common_logger'
35
- app = Rack::CommonLogger.new(app, STDOUT)
36
- end
37
-
38
- if options[:environment]
39
- user_config.environment options[:environment]
40
- end
41
-
42
- if options[:Threads]
43
- min, max = options.delete(:Threads).split(':', 2)
44
- user_config.threads min, max
45
- end
46
-
47
- if options[:Host] || options[:Port]
48
- host = options[:Host] || default_options[:Host]
49
- port = options[:Port] || default_options[:Port]
50
- self.set_host_port_to_config(host, port, user_config)
51
- end
52
-
53
- if default_options[:Host]
54
- file_config.set_default_host(default_options[:Host])
55
- end
56
- self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
57
-
58
- user_config.app app
32
+ conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
33
+ if options.delete(:Verbose)
34
+ require 'rack/common_logger'
35
+ app = Rack::CommonLogger.new(app, STDOUT)
59
36
  end
60
- conf
61
- end
62
37
 
63
- def self.run(app, **options)
64
- conf = self.config(app, options)
38
+ if options[:environment]
39
+ user_config.environment options[:environment]
40
+ end
65
41
 
66
- log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
42
+ if options[:Threads]
43
+ min, max = options.delete(:Threads).split(':', 2)
44
+ user_config.threads min, max
45
+ end
67
46
 
68
- launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer)
47
+ if options[:Host] || options[:Port]
48
+ host = options[:Host] || default_options[:Host]
49
+ port = options[:Port] || default_options[:Port]
50
+ self.set_host_port_to_config(host, port, user_config)
51
+ end
69
52
 
70
- yield launcher if block_given?
71
- begin
72
- launcher.run
73
- rescue Interrupt
74
- puts "* Gracefully stopping, waiting for requests to finish"
75
- launcher.stop
76
- puts "* Goodbye!"
53
+ if default_options[:Host]
54
+ file_config.set_default_host(default_options[:Host])
77
55
  end
56
+ self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
57
+
58
+ user_config.app app
78
59
  end
60
+ conf
61
+ end
62
+
63
+ def run(app, **options)
64
+ conf = self.config(app, options)
65
+
66
+ log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
79
67
 
80
- def self.valid_options
81
- {
82
- "Host=HOST" => "Hostname to listen on (default: localhost)",
83
- "Port=PORT" => "Port to listen on (default: 8080)",
84
- "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
85
- "Verbose" => "Don't report each request (default: false)"
86
- }
68
+ launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
69
+
70
+ yield launcher if block_given?
71
+ begin
72
+ launcher.run
73
+ rescue Interrupt
74
+ puts "* Gracefully stopping, waiting for requests to finish"
75
+ launcher.stop
76
+ puts "* Goodbye!"
87
77
  end
78
+ end
79
+
80
+ def valid_options
81
+ {
82
+ "Host=HOST" => "Hostname to listen on (default: localhost)",
83
+ "Port=PORT" => "Port to listen on (default: 8080)",
84
+ "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
85
+ "Verbose" => "Don't report each request (default: false)"
86
+ }
87
+ end
88
+
89
+ def set_host_port_to_config(host, port, config)
90
+ config.clear_binds! if host || port
91
+
92
+ if host && (host[0,1] == '.' || host[0,1] == '/')
93
+ config.bind "unix://#{host}"
94
+ elsif host && host =~ /^ssl:\/\//
95
+ uri = URI.parse(host)
96
+ uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
97
+ config.bind uri.to_s
98
+ else
88
99
 
89
- def self.set_host_port_to_config(host, port, config)
90
- config.clear_binds! if host || port
91
-
92
- if host && (host[0,1] == '.' || host[0,1] == '/')
93
- config.bind "unix://#{host}"
94
- elsif host && host =~ /^ssl:\/\//
95
- uri = URI.parse(host)
96
- uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
97
- config.bind uri.to_s
98
- else
99
-
100
- if host
101
- port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
102
- end
103
-
104
- if port
105
- host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
106
- config.port port, host
107
- end
100
+ if host
101
+ port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
102
+ end
103
+
104
+ if port
105
+ host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
106
+ config.port port, host
108
107
  end
109
108
  end
110
109
  end
110
+ end
111
+ end
111
112
 
112
- register :puma, Puma
113
+ # rackup was removed in Rack 3, it is now a separate gem
114
+ if Object.const_defined? :Rackup
115
+ module Rackup
116
+ module Handler
117
+ module Puma
118
+ class << self
119
+ include ::Puma::RackHandler
120
+ end
121
+ end
122
+ register :puma, Puma
123
+ end
124
+ end
125
+ else
126
+ do_register = Object.const_defined?(:Rack) && Rack::RELEASE < '3'
127
+ module Rack
128
+ module Handler
129
+ module Puma
130
+ class << self
131
+ include ::Puma::RackHandler
132
+ end
133
+ end
134
+ end
113
135
  end
136
+ ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
114
137
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
@@ -104,6 +104,7 @@ files:
104
104
  - lib/puma/minissl/context_builder.rb
105
105
  - lib/puma/null_io.rb
106
106
  - lib/puma/plugin.rb
107
+ - lib/puma/plugin/systemd.rb
107
108
  - lib/puma/plugin/tmp_restart.rb
108
109
  - lib/puma/rack/builder.rb
109
110
  - lib/puma/rack/urlmap.rb
@@ -111,10 +112,10 @@ files:
111
112
  - lib/puma/reactor.rb
112
113
  - lib/puma/request.rb
113
114
  - lib/puma/runner.rb
115
+ - lib/puma/sd_notify.rb
114
116
  - lib/puma/server.rb
115
117
  - lib/puma/single.rb
116
118
  - lib/puma/state_file.rb
117
- - lib/puma/systemd.rb
118
119
  - lib/puma/thread_pool.rb
119
120
  - lib/puma/util.rb
120
121
  - lib/rack/handler/puma.rb
@@ -144,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
145
  - !ruby/object:Gem::Version
145
146
  version: '0'
146
147
  requirements: []
147
- rubygems_version: 3.2.26
148
+ rubygems_version: 3.3.20
148
149
  signing_key:
149
150
  specification_version: 4
150
151
  summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
data/lib/puma/systemd.rb DELETED
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'sd_notify'
4
-
5
- module Puma
6
- class Systemd
7
- def initialize(log_writer, events)
8
- @log_writer = log_writer
9
- @events = events
10
- end
11
-
12
- def hook_events
13
- @events.on_booted { SdNotify.ready }
14
- @events.on_stopped { SdNotify.stopping }
15
- @events.on_restart { SdNotify.reloading }
16
- end
17
-
18
- def start_watchdog
19
- return unless SdNotify.watchdog?
20
-
21
- ping_f = watchdog_sleep_time
22
-
23
- log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
24
- Thread.new do
25
- loop do
26
- sleep ping_f
27
- SdNotify.watchdog
28
- end
29
- end
30
- end
31
-
32
- private
33
-
34
- def watchdog_sleep_time
35
- usec = Integer(ENV["WATCHDOG_USEC"])
36
-
37
- sec_f = usec / 1_000_000.0
38
- # "It is recommended that a daemon sends a keep-alive notification message
39
- # to the service manager every half of the time returned here."
40
- sec_f / 2
41
- end
42
-
43
- def log(str)
44
- @log_writer.log(str)
45
- end
46
- end
47
- end