puma 5.3.2-java → 5.5.2-java

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/minissl.rb CHANGED
@@ -161,30 +161,15 @@ module Puma
161
161
  @socket.flush
162
162
  end
163
163
 
164
- def read_and_drop(timeout = 1)
165
- return :timeout unless IO.select([@socket], nil, nil, timeout)
166
- case @socket.read_nonblock(1024, exception: false)
167
- when nil
168
- :eof
169
- when :wait_readable
170
- :eagain
171
- else
172
- :drop
173
- end
174
- end
175
-
176
- def should_drop_bytes?
177
- @engine.init? || !@engine.shutdown
178
- end
179
-
180
164
  def close
181
165
  begin
182
- # Read any drop any partially initialized sockets and any received bytes during shutdown.
183
- # Don't let this socket hold this loop forever.
184
- # If it can't send more packets within 1s, then give up.
185
- return if [:timeout, :eof].include?(read_and_drop(1)) while should_drop_bytes?
166
+ unless @engine.shutdown
167
+ while alert_data = @engine.extract
168
+ @socket.write alert_data
169
+ end
170
+ end
186
171
  rescue IOError, SystemCallError
187
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
172
+ Puma::Util.purge_interrupt_queue
188
173
  # nothing
189
174
  ensure
190
175
  @socket.close
data/lib/puma/plugin.rb CHANGED
@@ -91,7 +91,7 @@ module Puma
91
91
  path = ary.first[CALLER_FILE]
92
92
 
93
93
  m = %r!puma/plugin/([^/]*)\.rb$!.match(path)
94
- return m[1]
94
+ m[1]
95
95
  end
96
96
 
97
97
  def self.create(&blk)
Binary file
@@ -165,7 +165,7 @@ module Puma::Rack
165
165
  require config
166
166
  app = Object.const_get(::File.basename(config, '.rb').capitalize)
167
167
  end
168
- return app, options
168
+ [app, options]
169
169
  end
170
170
 
171
171
  def self.new_from_string(builder_script, file="(rackup)")
data/lib/puma/request.rb CHANGED
@@ -51,7 +51,7 @@ module Puma
51
51
  head = env[REQUEST_METHOD] == HEAD
52
52
 
53
53
  env[RACK_INPUT] = body
54
- env[RACK_URL_SCHEME] = default_server_port(env) == PORT_443 ? HTTPS : HTTP
54
+ env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP
55
55
 
56
56
  if @early_hints
57
57
  env[EARLY_HINTS] = lambda { |headers|
@@ -176,7 +176,7 @@ module Puma
176
176
  after_reply.each { |o| o.call }
177
177
  end
178
178
 
179
- return res_info[:keep_alive]
179
+ res_info[:keep_alive]
180
180
  end
181
181
 
182
182
  # @param env [Hash] see Puma::Client#env, from request
@@ -201,7 +201,7 @@ module Puma
201
201
  begin
202
202
  n = io.syswrite str
203
203
  rescue Errno::EAGAIN, Errno::EWOULDBLOCK
204
- if !IO.select(nil, [io], nil, WRITE_TIMEOUT)
204
+ unless io.wait_writable WRITE_TIMEOUT
205
205
  raise ConnectionError, "Socket timeout writing data"
206
206
  end
207
207
 
@@ -419,7 +419,7 @@ module Puma
419
419
  # of concurrent connections exceeds the size of the threadpool.
420
420
  res_info[:keep_alive] &&= requests < @max_fast_inline ||
421
421
  @thread_pool.busy_threads < @max_threads ||
422
- !IO.select([client.listener], nil, nil, 0)
422
+ !client.listener.to_io.wait_readable(0)
423
423
 
424
424
  res_info[:response_hijack] = nil
425
425
 
data/lib/puma/runner.rb CHANGED
@@ -15,6 +15,16 @@ module Puma
15
15
  @app = nil
16
16
  @control = nil
17
17
  @started_at = Time.now
18
+ @wakeup = nil
19
+ end
20
+
21
+ def wakeup!
22
+ return unless @wakeup
23
+
24
+ @wakeup.write "!" unless @wakeup.closed?
25
+
26
+ rescue SystemCallError, IOError
27
+ Puma::Util.purge_interrupt_queue
18
28
  end
19
29
 
20
30
  def development?
@@ -108,9 +118,7 @@ module Puma
108
118
  append = @options[:redirect_append]
109
119
 
110
120
  if stdout
111
- unless Dir.exist?(File.dirname(stdout))
112
- raise "Cannot redirect STDOUT to #{stdout}"
113
- end
121
+ ensure_output_directory_exists(stdout, 'STDOUT')
114
122
 
115
123
  STDOUT.reopen stdout, (append ? "a" : "w")
116
124
  STDOUT.puts "=== puma startup: #{Time.now} ==="
@@ -118,9 +126,7 @@ module Puma
118
126
  end
119
127
 
120
128
  if stderr
121
- unless Dir.exist?(File.dirname(stderr))
122
- raise "Cannot redirect STDERR to #{stderr}"
123
- end
129
+ ensure_output_directory_exists(stderr, 'STDERR')
124
130
 
125
131
  STDERR.reopen stderr, (append ? "a" : "w")
126
132
  STDERR.puts "=== puma startup: #{Time.now} ==="
@@ -159,5 +165,12 @@ module Puma
159
165
  server.inherit_binder @launcher.binder
160
166
  server
161
167
  end
168
+
169
+ private
170
+ def ensure_output_directory_exists(path, io_name)
171
+ unless Dir.exist?(File.dirname(path))
172
+ raise "Cannot redirect #{io_name} to #{path}"
173
+ end
174
+ end
162
175
  end
163
176
  end
data/lib/puma/server.rb CHANGED
@@ -14,6 +14,7 @@ require 'puma/io_buffer'
14
14
  require 'puma/request'
15
15
 
16
16
  require 'socket'
17
+ require 'io/wait'
17
18
  require 'forwardable'
18
19
 
19
20
  module Puma
@@ -145,7 +146,7 @@ module Puma
145
146
  begin
146
147
  skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket
147
148
  rescue IOError, SystemCallError
148
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
149
+ Puma::Util.purge_interrupt_queue
149
150
  end
150
151
  end
151
152
 
@@ -154,7 +155,7 @@ module Puma
154
155
  begin
155
156
  skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket
156
157
  rescue IOError, SystemCallError
157
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
158
+ Puma::Util.purge_interrupt_queue
158
159
  end
159
160
  end
160
161
  else
@@ -175,7 +176,7 @@ module Puma
175
176
  begin
176
177
  tcp_info = skt.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO)
177
178
  rescue IOError, SystemCallError
178
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
179
+ Puma::Util.purge_interrupt_queue
179
180
  @precheck_closing = false
180
181
  false
181
182
  else
@@ -227,6 +228,7 @@ module Puma
227
228
  @status = :run
228
229
 
229
230
  @thread_pool = ThreadPool.new(
231
+ thread_name,
230
232
  @min_threads,
231
233
  @max_threads,
232
234
  ::Puma::IOBuffer,
@@ -321,6 +323,8 @@ module Puma
321
323
  remote_addr_value = @options[:remote_address_value]
322
324
  when :header
323
325
  remote_addr_header = @options[:remote_address_header]
326
+ when :proxy_protocol
327
+ remote_addr_proxy_protocol = @options[:remote_address_proxy_protocol]
324
328
  end
325
329
 
326
330
  while @status == :run || (drain && shutting_down?)
@@ -346,11 +350,16 @@ module Puma
346
350
  client.peerip = remote_addr_value
347
351
  elsif remote_addr_header
348
352
  client.remote_addr_header = remote_addr_header
353
+ elsif remote_addr_proxy_protocol
354
+ client.expect_proxy_proto = remote_addr_proxy_protocol
349
355
  end
350
356
  pool << client
351
357
  end
352
358
  end
353
- rescue Object => e
359
+ rescue IOError, Errno::EBADF
360
+ # In the case that any of the sockets are unexpectedly close.
361
+ raise
362
+ rescue StandardError => e
354
363
  @events.unknown_error e, nil, "Listen loop"
355
364
  end
356
365
  end
@@ -396,7 +405,7 @@ module Puma
396
405
  return true
397
406
  end
398
407
 
399
- return false
408
+ false
400
409
  end
401
410
 
402
411
  # Given a connection on +client+, handle the incoming requests,
@@ -482,7 +491,7 @@ module Puma
482
491
  begin
483
492
  client.close if close_socket
484
493
  rescue IOError, SystemCallError
485
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
494
+ Puma::Util.purge_interrupt_queue
486
495
  # Already closed
487
496
  rescue StandardError => e
488
497
  @events.unknown_error e, nil, "Client"
@@ -574,11 +583,11 @@ module Puma
574
583
  @notify << message
575
584
  rescue IOError, NoMethodError, Errno::EPIPE
576
585
  # The server, in another thread, is shutting down
577
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
586
+ Puma::Util.purge_interrupt_queue
578
587
  rescue RuntimeError => e
579
588
  # Temporary workaround for https://bugs.ruby-lang.org/issues/13239
580
589
  if e.message.include?('IOError')
581
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
590
+ Puma::Util.purge_interrupt_queue
582
591
  else
583
592
  raise e
584
593
  end
@@ -29,7 +29,7 @@ module Puma
29
29
  # The block passed is the work that will be performed in each
30
30
  # thread.
31
31
  #
32
- def initialize(min, max, *extra, &block)
32
+ def initialize(name, min, max, *extra, &block)
33
33
  @not_empty = ConditionVariable.new
34
34
  @not_full = ConditionVariable.new
35
35
  @mutex = Mutex.new
@@ -39,6 +39,7 @@ module Puma
39
39
  @spawned = 0
40
40
  @waiting = 0
41
41
 
42
+ @name = name
42
43
  @min = Integer(min)
43
44
  @max = Integer(max)
44
45
  @block = block
@@ -101,7 +102,7 @@ module Puma
101
102
  @spawned += 1
102
103
 
103
104
  th = Thread.new(@spawned) do |spawned|
104
- Puma.set_thread_name 'threadpool %03i' % spawned
105
+ Puma.set_thread_name '%s threadpool %03i' % [@name, spawned]
105
106
  todo = @todo
106
107
  block = @block
107
108
  mutex = @mutex
@@ -119,6 +120,7 @@ module Puma
119
120
  @trim_requested -= 1
120
121
  @spawned -= 1
121
122
  @workers.delete th
123
+ not_full.signal
122
124
  Thread.exit
123
125
  end
124
126
 
@@ -318,12 +320,12 @@ module Puma
318
320
  end
319
321
 
320
322
  def auto_trim!(timeout=30)
321
- @auto_trim = Automaton.new(self, timeout, "threadpool trimmer", :trim)
323
+ @auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
322
324
  @auto_trim.start!
323
325
  end
324
326
 
325
327
  def auto_reap!(timeout=5)
326
- @reaper = Automaton.new(self, timeout, "threadpool reaper", :reap)
328
+ @reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
327
329
  @reaper.start!
328
330
  end
329
331
 
data/lib/puma/util.rb CHANGED
@@ -10,6 +10,13 @@ module Puma
10
10
  IO.pipe
11
11
  end
12
12
 
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
15
+ # Additional context: https://github.com/puma/puma/pull/1345
16
+ def purge_interrupt_queue
17
+ Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
18
+ end
19
+
13
20
  # Unescapes a URI escaped string with +encoding+. +encoding+ will be the
14
21
  # target encoding of the string returned, and it defaults to UTF-8
15
22
  if defined?(::Encoding)
@@ -61,7 +68,7 @@ module Puma
61
68
  end
62
69
  end
63
70
 
64
- return params
71
+ params
65
72
  end
66
73
 
67
74
  # A case-insensitive Hash that preserves the original case of a
data/lib/puma.rb CHANGED
@@ -12,7 +12,7 @@ require 'thread'
12
12
 
13
13
  require 'puma/puma_http11'
14
14
  require 'puma/detect'
15
- require 'puma/json'
15
+ require 'puma/json_serialization'
16
16
 
17
17
  module Puma
18
18
  autoload :Const, 'puma/const'
@@ -60,7 +60,7 @@ module Puma
60
60
 
61
61
  # @!attribute [rw] stats_object
62
62
  def self.stats
63
- Puma::JSON.generate @get_stats.stats
63
+ Puma::JSONSerialization.generate @get_stats.stats
64
64
  end
65
65
 
66
66
  # @!attribute [r] stats_hash
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: 5.3.2
4
+ version: 5.5.2
5
5
  platform: java
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-21 00:00:00.000000000 Z
11
+ date: 2021-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -24,9 +24,9 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
- description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
27
+ description: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server
28
28
  for Ruby/Rack applications. Puma is intended for use in both development and production
29
- environments. It's great for highly concurrent Ruby implementations such as Rubinius
29
+ environments. It's great for highly parallel Ruby implementations such as Rubinius
30
30
  and JRuby as well as as providing process worker support to support CRuby well.
31
31
  email:
32
32
  - evan@phx.io
@@ -93,7 +93,7 @@ files:
93
93
  - lib/puma/events.rb
94
94
  - lib/puma/io_buffer.rb
95
95
  - lib/puma/jruby_restart.rb
96
- - lib/puma/json.rb
96
+ - lib/puma/json_serialization.rb
97
97
  - lib/puma/launcher.rb
98
98
  - lib/puma/minissl.rb
99
99
  - lib/puma/minissl/context_builder.rb
@@ -143,6 +143,6 @@ requirements: []
143
143
  rubygems_version: 3.1.6
144
144
  signing_key:
145
145
  specification_version: 4
146
- summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
146
+ summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
147
147
  Ruby/Rack applications
148
148
  test_files: []