Skip to content

Commit 6dac5d9

Browse files
JoeDupuisMSP-Greg
andauthored
Prevent loading with rack 3 (#3166)
* Prevent booting with rack 3 * Move with_unbundled_env to integration helpers * Version restriction test environment * Allow skipping the wait period with the cli_server helper * Test for the rack version restriction * Fixup & Rename test file * Minor puma.rb and rack/version_restriction.rb changes --------- Co-authored-by: MSP-Greg <Greg.mpls@gmail.com>
1 parent 0892558 commit 6dac5d9

7 files changed

Lines changed: 83 additions & 13 deletions

File tree

lib/puma.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010

1111
require 'thread'
1212

13+
# extension files should not be loaded with `require_relative`
1314
require 'puma/puma_http11'
14-
require 'puma/detect'
15-
require 'puma/json_serialization'
15+
require_relative 'puma/detect'
16+
require_relative 'puma/json_serialization'
17+
require_relative 'rack/version_restriction'
1618

1719
module Puma
1820
autoload :Const, 'puma/const'

lib/rack/version_restriction.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
begin
2+
begin
3+
# rack/version exists in Rack 2.2.0 and later, compatible with Ruby 2.3 and later
4+
# we prefer to not load Rack
5+
require 'rack/version'
6+
rescue LoadError
7+
require 'rack'
8+
end
9+
10+
# Rack.release is needed for Rack v1, Rack::RELEASE was added in v2
11+
if Gem::Version.new(Rack.release) >= Gem::Version.new("3.0.0")
12+
raise StandardError.new "Puma 5 is not compatible with Rack 3, please upgrade to Puma 6 or higher."
13+
end
14+
rescue LoadError
15+
end

test/bundle_rack_3/Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source "https://rubygems.org"
2+
3+
gem 'rack', '>= 3.0.0'
4+
gem 'puma', path: '../..'

test/bundle_rack_3/config.ru

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello World"]] }

test/helpers/integration.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,20 @@ def teardown
5454

5555
private
5656

57+
def with_unbundled_env
58+
bundler_ver = Gem::Version.new(Bundler::VERSION)
59+
if bundler_ver < Gem::Version.new('2.1.0')
60+
Bundler.with_clean_env { yield }
61+
else
62+
Bundler.with_unbundled_env { yield }
63+
end
64+
end
65+
5766
def silent_and_checked_system_command(*args)
5867
assert(system(*args, out: File::NULL, err: File::NULL))
5968
end
6069

61-
def cli_server(argv, unix: false, config: nil, merge_err: false)
70+
def cli_server(argv, unix: false, config: nil, merge_err: false, skip_waiting: false)
6271
if config
6372
config_file = Tempfile.new(%w(config .rb))
6473
config_file.write config
@@ -77,7 +86,7 @@ def cli_server(argv, unix: false, config: nil, merge_err: false)
7786
else
7887
@server = IO.popen(cmd, "r")
7988
end
80-
wait_for_server_to_boot
89+
wait_for_server_to_boot unless skip_waiting
8190
@pid = @server.pid
8291
@server
8392
end
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require_relative "helper"
2+
require_relative "helpers/integration"
3+
4+
class TestRackVersionRestriction < TestIntegration
5+
class PumaBooted < Timeout::Error; end
6+
7+
def setup
8+
# Rack 3 minimum Ruby version is 2.4
9+
skip if !::Puma::IS_MRI || RUBY_VERSION < '2.4'
10+
super
11+
end
12+
13+
def teardown
14+
return if skipped?
15+
FileUtils.rm_rf ["#{workdir}/vendor", "#{workdir}/Gemfile.lock"]
16+
begin
17+
# KILL works with all OS's
18+
Process.kill(:KILL, @server.pid) if @server
19+
rescue Errno::ESRCH
20+
end
21+
end
22+
23+
def test_prevent_booting_with_rack_3
24+
msg = "Puma 5 is not compatible with Rack 3"
25+
puma_crashed = false
26+
27+
Dir.chdir(workdir) do
28+
with_unbundled_env do
29+
silent_and_checked_system_command("bundle config --local path vendor/bundle")
30+
silent_and_checked_system_command("bundle install")
31+
Timeout.timeout(5, PumaBooted) do
32+
cli_server './config.ru', merge_err: true, skip_waiting: true
33+
sleep 0.1 until puma_crashed = @server.gets[msg]
34+
end
35+
end
36+
end
37+
38+
rescue PumaBooted
39+
ensure
40+
assert puma_crashed, "Puma was expected to crash on boot, but it didn't! "
41+
end
42+
43+
private
44+
45+
def workdir
46+
File.expand_path("bundle_rack_3", __dir__)
47+
end
48+
end

test/test_worker_gem_independence.rb

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,4 @@ def start_phased_restart
133133

134134
true while @server.gets !~ /booted in [.0-9]+s, phase: 1/
135135
end
136-
137-
def with_unbundled_env
138-
bundler_ver = Gem::Version.new(Bundler::VERSION)
139-
if bundler_ver < Gem::Version.new('2.1.0')
140-
Bundler.with_clean_env { yield }
141-
else
142-
Bundler.with_unbundled_env { yield }
143-
end
144-
end
145136
end

0 commit comments

Comments
 (0)