puma 5.2.0 → 5.2.1

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4d9b1bd7562eeb74d7f1045f732667a6b9ab3c9b51fa602c1679017b79450d6
4
- data.tar.gz: d287f603974f6aaf5e16610ae5528c086595a1b1dc026343b7155443c2c0f10a
3
+ metadata.gz: d702fffe078664ed49a411a31910737455c819d6acadd3875c89e00368f68dd8
4
+ data.tar.gz: 972f53b07a05363ff839b6f176150bdf4cbc19f7445601ad10f41e9bcaf73af2
5
5
  SHA512:
6
- metadata.gz: 6db9d8631ed272b1a405eec838414949314154f1e4d9cb95d825ec9a85ade7eaf66180771e89da58845089d824f34af53cd58c18b5bb85e12accb47184e1724c
7
- data.tar.gz: 13c7da69b1dc0f25da9583baa0d235531ad67efe824f12decc9e6d65b3573bf193119d15f7800a5980cc1ca9d4e67cebb5ebf2d6d1abb4d95ca54e8ac653a327
6
+ metadata.gz: fff3451918f8e34324189c0fa6c161baa1860181920f934541a4db9b5e484d20edae74dd9ac33baa3c14514c75d052cbb5d42539f371bf33cca82e644aa52c57
7
+ data.tar.gz: 86c7ba8cb909bedb1dceb259d28677295a71e66b53ed1f1fb6ce324ddab0dbe05c5469aaa120f50f7427cc257d6fa6b6898c7b0346810871f1fceb2ad25bab93
data/History.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 5.2.1 / 2021-02-05
2
+
3
+ * Bugfixes
4
+ * Fix TCP cork/uncork operations to work with ssl clients ([#2550])
5
+ * Require rack/common_logger explicitly if :verbose is true ([#2547])
6
+ * MiniSSL::Socket#write - use data.byteslice(wrote..-1) ([#2543])
7
+ * Set `@env[CONTENT_LENGTH]` value as string. ([#2549])
8
+
1
9
  ## 5.2.0 / 2021-01-27
2
10
 
3
11
  * Features
@@ -1694,6 +1702,10 @@ be added back in a future date when a java Puma::MiniSSL is added.
1694
1702
  * Bugfixes
1695
1703
  * Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
1696
1704
 
1705
+ [#2550]:https://github.com/puma/puma/pull/2550 "PR by @MSP-Greg, merged 2021-02-05"
1706
+ [#2547]:https://github.com/puma/puma/pull/2547 "PR by @wildmaples, merged 2021-02-03"
1707
+ [#2543]:https://github.com/puma/puma/pull/2543 "PR by @MSP-Greg, merged 2021-02-01"
1708
+ [#2549]:https://github.com/puma/puma/pull/2549 "PR by @nmb, merged 2021-02-04"
1697
1709
  [#2519]:https://github.com/puma/puma/pull/2519 "PR by @MSP-Greg, merged 2021-01-26"
1698
1710
  [#2522]:https://github.com/puma/puma/pull/2522 "PR by @jcmfernandes, merged 2021-01-12"
1699
1711
  [#2490]:https://github.com/puma/puma/pull/2490 "PR by @Bonias, merged 2020-12-07"
@@ -0,0 +1,29 @@
1
+ # Running Puma in Rails Development Mode
2
+
3
+ ## "Loopback requests"
4
+
5
+ Be cautious of "loopback requests", where a Rails application executes a request to a server that in turn, results in another request back to the same Rails application before the first request is completed. Having a loopback request will trigger [Rails' load interlock](https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock) mechanism. The load interlock mechanism prevents a thread from using Rails autoloading mechanism to load constants while the application code is still running inside another thread.
6
+
7
+ This issue only occurs in the development environment as Rails' load interlock is not used in production environments. Although we're not sure, we believe this issue may not occur with the new `zeitwerk` code loader.
8
+
9
+ ### Solutions
10
+
11
+
12
+ #### 1. Bypass Rails' load interlock with `.permit_concurrent_loads`
13
+
14
+ Wrap the first request inside a block that will allow concurrent loads, [`ActiveSupport::Dependencies.interlock.permit_concurrent_loads`](https://guides.rubyonrails.org/threading_and_code_execution.html#permit-concurrent-loads). Anything wrapped inside the `.permit_concurrent_loads` block will bypass the load interlock mechanism, allowing new threads to access the Rails environment and boot properly.
15
+
16
+ ###### Example
17
+
18
+ ```ruby
19
+ response = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
20
+ # Your HTTP request code here. For example:
21
+ Faraday.post url, data: 'foo'
22
+ end
23
+
24
+ do_something_with response
25
+ ```
26
+
27
+ #### 2. Use multiple processes on Puma
28
+
29
+ Alternatively, you may also enable multiple (single-threaded) workers on Puma. By doing so, you are sidestepping the problem by creating multiple processes rather than new threads. However, this workaround is not ideal because debugging tools such as [byebug](https://github.com/deivid-rodriguez/byebug/issues/487) and [pry](https://github.com/pry/pry/issues/2153), work poorly with any multi-process web server.
data/lib/puma.rb CHANGED
@@ -19,6 +19,24 @@ module Puma
19
19
  autoload :Server, 'puma/server'
20
20
  autoload :Launcher, 'puma/launcher'
21
21
 
22
+ # at present, MiniSSL::Engine is only defined in extension code (puma_http11),
23
+ # not in minissl.rb
24
+ HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
25
+
26
+ if HAS_SSL
27
+ require 'puma/minissl'
28
+ else
29
+ module MiniSSL
30
+ # this class is defined so that it exists when Puma is compiled
31
+ # without ssl support, as Server and Reactor use it in rescue statements.
32
+ class SSLError < StandardError ; end
33
+ end
34
+ end
35
+
36
+ def self.ssl?
37
+ HAS_SSL
38
+ end
39
+
22
40
  # @!attribute [rw] stats_object=
23
41
  def self.stats_object=(val)
24
42
  @get_stats = val
@@ -40,12 +58,4 @@ module Puma
40
58
  return unless Thread.current.respond_to?(:name=)
41
59
  Thread.current.name = "puma #{name}"
42
60
  end
43
-
44
- unless HAS_SSL
45
- module MiniSSL
46
- # this class is defined so that it exists when Puma is compiled
47
- # without ssl support, as Server and Reactor use it in rescue statements.
48
- class SSLError < StandardError ; end
49
- end
50
- end
51
61
  end
data/lib/puma/client.rb CHANGED
@@ -374,7 +374,7 @@ module Puma
374
374
  end
375
375
 
376
376
  if decode_chunk(chunk)
377
- @env[CONTENT_LENGTH] = @chunked_content_length
377
+ @env[CONTENT_LENGTH] = @chunked_content_length.to_s
378
378
  return true
379
379
  end
380
380
  end
@@ -391,7 +391,7 @@ module Puma
391
391
  @chunked_content_length = 0
392
392
 
393
393
  if decode_chunk(body)
394
- @env[CONTENT_LENGTH] = @chunked_content_length
394
+ @env[CONTENT_LENGTH] = @chunked_content_length.to_s
395
395
  return true
396
396
  end
397
397
  end
data/lib/puma/const.rb CHANGED
@@ -100,7 +100,7 @@ module Puma
100
100
  # too taxing on performance.
101
101
  module Const
102
102
 
103
- PUMA_VERSION = VERSION = "5.2.0".freeze
103
+ PUMA_VERSION = VERSION = "5.2.1".freeze
104
104
  CODE_NAME = "Fettisdagsbulle".freeze
105
105
 
106
106
  PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
data/lib/puma/detect.rb CHANGED
@@ -1,32 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # This file can be loaded independently of puma.rb, so it cannot have any code
4
+ # that assumes puma.rb is loaded.
5
+
6
+
3
7
  module Puma
4
- # at present, MiniSSL::Engine is only defined in extension code, not in minissl.rb
5
- HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
8
+ # @version 5.2.1
9
+ HAS_FORK = ::Process.respond_to? :fork
6
10
 
7
- def self.ssl?
8
- HAS_SSL
9
- end
11
+ IS_JRUBY = Object.const_defined? :JRUBY_VERSION
10
12
 
11
- IS_JRUBY = defined?(JRUBY_VERSION)
13
+ IS_WINDOWS = !!(RUBY_PLATFORM =~ /mswin|ming|cygwin/ ||
14
+ IS_JRUBY && RUBY_DESCRIPTION =~ /mswin/)
15
+
16
+ # @version 5.2.0
17
+ IS_MRI = (RUBY_ENGINE == 'ruby' || RUBY_ENGINE.nil?)
12
18
 
13
19
  def self.jruby?
14
20
  IS_JRUBY
15
21
  end
16
22
 
17
- IS_WINDOWS = RUBY_PLATFORM =~ /mswin|ming|cygwin/
18
-
19
23
  def self.windows?
20
24
  IS_WINDOWS
21
25
  end
22
26
 
23
27
  # @version 5.0.0
24
28
  def self.mri?
25
- RUBY_ENGINE == 'ruby' || RUBY_ENGINE.nil?
29
+ IS_MRI
26
30
  end
27
31
 
28
32
  # @version 5.0.0
29
33
  def self.forkable?
30
- ::Process.respond_to?(:fork)
34
+ HAS_FORK
31
35
  end
32
36
  end
data/lib/puma/minissl.rb CHANGED
@@ -133,7 +133,7 @@ module Puma
133
133
 
134
134
  return data_size if need == 0
135
135
 
136
- data = data[wrote..-1]
136
+ data = data.byteslice(wrote..-1)
137
137
  end
138
138
  end
139
139
 
data/lib/puma/request.rb CHANGED
@@ -30,7 +30,7 @@ module Puma
30
30
  #
31
31
  def handle_request(client, lines)
32
32
  env = client.env
33
- io = client.io
33
+ io = client.io # io may be a MiniSSL::Socket
34
34
 
35
35
  return false if closed_socket?(io)
36
36
 
data/lib/puma/server.rb CHANGED
@@ -120,17 +120,13 @@ module Puma
120
120
  # :nodoc:
121
121
  # @version 5.0.0
122
122
  def tcp_cork_supported?
123
- RbConfig::CONFIG['host_os'] =~ /linux/ &&
124
- Socket.const_defined?(:IPPROTO_TCP) &&
125
- Socket.const_defined?(:TCP_CORK)
123
+ Socket.const_defined?(:TCP_CORK) && Socket.const_defined?(:IPPROTO_TCP)
126
124
  end
127
125
 
128
126
  # :nodoc:
129
127
  # @version 5.0.0
130
128
  def closed_socket_supported?
131
- RbConfig::CONFIG['host_os'] =~ /linux/ &&
132
- Socket.const_defined?(:IPPROTO_TCP) &&
133
- Socket.const_defined?(:TCP_INFO)
129
+ Socket.const_defined?(:TCP_INFO) && Socket.const_defined?(:IPPROTO_TCP)
134
130
  end
135
131
  private :tcp_cork_supported?
136
132
  private :closed_socket_supported?
@@ -138,6 +134,7 @@ module Puma
138
134
 
139
135
  # On Linux, use TCP_CORK to better control how the TCP stack
140
136
  # packetizes our stream. This improves both latency and throughput.
137
+ # socket parameter may be an MiniSSL::Socket, so use to_io
141
138
  #
142
139
  if tcp_cork_supported?
143
140
  UNPACK_TCP_STATE_FROM_TCP_INFO = "C".freeze
@@ -146,16 +143,18 @@ module Puma
146
143
  # 3 == TCP_CORK
147
144
  # 1/0 == turn on/off
148
145
  def cork_socket(socket)
146
+ skt = socket.to_io
149
147
  begin
150
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if socket.kind_of? TCPSocket
148
+ skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket
151
149
  rescue IOError, SystemCallError
152
150
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
153
151
  end
154
152
  end
155
153
 
156
154
  def uncork_socket(socket)
155
+ skt = socket.to_io
157
156
  begin
158
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if socket.kind_of? TCPSocket
157
+ skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket
159
158
  rescue IOError, SystemCallError
160
159
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
161
160
  end
@@ -31,6 +31,7 @@ module Rack
31
31
 
32
32
  conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
33
33
  if options.delete(:Verbose)
34
+ require 'rack/common_logger'
34
35
  app = Rack::CommonLogger.new(app, STDOUT)
35
36
  end
36
37
 
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.2.0
4
+ version: 5.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-27 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r
@@ -57,6 +57,7 @@ files:
57
57
  - docs/kubernetes.md
58
58
  - docs/nginx.md
59
59
  - docs/plugins.md
60
+ - docs/rails_dev_mode.md
60
61
  - docs/restart.md
61
62
  - docs/signals.md
62
63
  - docs/stats.md