puma: Error in reactor loop escaped: System error: Undefined error: 0 - 0 (Puma::MiniSSL::SSLError)
I am setting up capybara to use SSL through puma. It all works in terms of connectivity, but this gets puts
ed out to STDOUT
and I can find no way to fix it or silence it. I’m ok with either as a solution.
Steps to reproduce
- Setup SSL as such:
# https://gist.github.com/tadast/9932075
if Rails.env.test?
unless File.exist?(Rails.root.join('config', 'ssl', 'localhost.test.key'))
def generate_root_cert(root_key)
root_ca = OpenSSL::X509::Certificate.new
root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
root_ca.serial = 0x0
root_ca.subject = OpenSSL::X509::Name.parse "/C=BE/O=A1/OU=A/CN=localhost.test"
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
root_ca.public_key = root_key.public_key
root_ca.not_before = Time.now
root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
root_ca
end
root_key = OpenSSL::PKey::RSA.new(2048)
file = File.new( Rails.root.join('config', 'ssl', 'localhost.test.key'), "wb")
file.write(root_key)
file.close
root_cert = generate_root_cert(root_key)
file = File.new( Rails.root.join('config','ssl', 'localhost.test.crt'), "wb")
file.write(root_cert)
file.close
end
ssl_bind 'localhost.test', 3000, {
key: Rails.root.join('config','ssl', 'localhost.test.key'),
cert: Rails.root.join('config','ssl', 'localhost.test.crt'),
verify_mode: 'none'
}
end
- Run Rspec feature specs using capybara, headless chrome, and puma
# https://robots.thoughtbot.com/headless-feature-specs-with-chrome
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.register_driver :headless_chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: {
args: %w(headless disable-gpu),
'profile.managed_default_content_settings.notifications': 2,
}
)
profile = Selenium::WebDriver::Chrome::Profile.new
profile["profile.default_content_settings"] = { images: '2' }
options = Selenium::WebDriver::Chrome::Options.new(args: ['headless', '--blink-settings=imagesEnabled=false'])
Capybara::Selenium::Driver.new app,
browser: :chrome,
desired_capabilities: capabilities,
profile: profile,
options: options
end
Capybara.javascript_driver = :headless_chrome
# If you’d like to watch the tests execute while debugging, you can change the driver to chrome.
# Capybara.javascript_driver = :chrome
# Screenshot with save_and_open_screenshot
key_file = Rails.root.join('config', 'ssl', 'localhost.test.key')
cert_file = Rails.root.join('config', 'ssl', 'localhost.test.crt')
Capybara.server = :puma, {
Silent: true,
Host: "ssl://#{Capybara.server_host}:#{Capybara.server_port}?key=#{key_file}&cert=#{cert_file}"
}
Expected behavior
I would expect Silent: true
to actually keep things silent.
Actual behavior
I get the following puts
on every run:
Error in reactor loop escaped: System error: Undefined error: 0 - 0 (Puma::MiniSSL::SSLError)
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/minissl.rb:41:in `read'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/minissl.rb:41:in `engine_read_all'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/minissl.rb:52:in `read_nonblock'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/minissl.rb:127:in `read_and_drop'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/minissl.rb:144:in `close'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/client.rb:123:in `close'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/reactor.rb:212:in `rescue in block in run_internal'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/reactor.rb:170:in `block in run_internal'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/reactor.rb:140:in `each'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/reactor.rb:140:in `run_internal'
/Users/[REDACTED]/.rvm/gems/ruby-2.5.3@[REDACTED]/gems/puma-3.12.0/lib/puma/reactor.rb:251:in `block in run_in_thread'
System configuration
Ruby version: 2.5.3 Rails version: 5.2.2 Puma version: 3.12.0
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 11
- Comments: 32 (14 by maintainers)
@hwhelchel
Not right now. This is a bit messy, as I’m not sure if the issue is specific to OpenSSL 1.1.1 or not. If it is, it might point to an issue in minissl.rb or minissl.c.
Regardless, I think expecting a socket to close when it has already generated an error is dicey. The main thing Puma should be doing is removing it from the reactor, closing it might even be something that GC could do, especially if we assume autoclose is always true. Haven’t checked.
It could be a malicious connection, which might be better to ignore.
Sorry for generalizing things.
@MSP-Greg switching to
c.close rescue nil
on line 266 silenced the error. Switching toc.close unless c.closed?
had no effect. Looks likec.close rescue nil
on line 266 is what we want.@hwhelchel
Two other suggestions, replace: https://github.com/puma/puma/blob/5fef2b715fdb69697161b21585c118995b6ee399/lib/puma/reactor.rb#L266 with:
or
Sorry there’s a bit more to the incantation than I thought.
Looks like this needs someone to think through Greg’s concerns a bit more and then submit a PR.