New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Puma to compile when built without SSL, load SSL files on demand #2305
Conversation
f364079
to
68cc2df
Compare
Thanks for the quick work on this! Sorry it took me a while to test it, complications. But I just gave it a go and it works great. 👍 |
lib/puma/minissl.rb
Outdated
@@ -308,5 +307,5 @@ def close | |||
@socket.close unless @socket.closed? # closed? call is for Windows | |||
end | |||
end | |||
end | |||
end if IS_JRUBY || (Puma::MiniSSL.check.nil? rescue nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a better check, silently skipping tests if e.g. there is a typo, seems bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That check is to not load minissl.rb if MRI Puma wasn't compiled with SSL support. Similar checks for some of the tests also. The silent skips will only happen when Puma isn't compiled with SSL support. I'm working with it in my fork (adding a 'none SSL' job) and locally. JFYI, working with JRuby head locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can leave a comment (or add a new method to Puma detect) to explain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Let me think about that (MRI/JRuby/TruffleRuby). Puma detect is good, but it overlaps with Puma::MiniSSL.check
. Maybe lose Puma::MiniSSL.check
and have a method in detect that returns a boolean rather than the damn error in Puma::MiniSSL.check
. Someone using it with UNIXSockets may chose to compile without OpenSSL... Sorry, rant off.
Hmm, how do we want to do CI for this? Just trigger it with an environment variable? |
I was looking at that this week, and didn't finish. extconf.rb works with MRI, but I'm not sure about other platforms? |
Well MRI is the only platform we're worried about supporting w/o SSL, though, right? |
No, I need to check it with JRuby, I'll also check against TruffleRuby, but I think it should behave similar to MRI... (?) |
I believe I've got JRuby compiling without OpenSSL (simple changes). At present, runtime SSL detection is kind of odd (putting that nicely). I hate using I think a better way is checking what classes exist in Question - Since A goal is to not need to require Ruby's OpenSSL if Puma is compiled without OpenSSL... |
Makes sense! |
Two items:
|
a9c1c8c
to
c2624ae
Compare
This is done, updated notes, etc. JRuby & TruffleRuby still intermittently lock up in testing. The last pair of jobs in my fork both passed, using JRuby for the 'no ssl' workflow (not jruby-head). |
e04335f
to
e20b7e8
Compare
I just pushed an update. Before, the code to determine whether Puma was built with ssl in detect.rb was: HAS_SSL = const_defined?(:MiniSSL, false) Updated code is: # at present, MiniSSL::Engine is only defined in extension code, not in minissl.rb
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
require 'puma/configuration' | ||
|
||
module Puma | ||
|
||
if HAS_SSL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of moving these from the top of the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could move it above and use Puma::HAS_SSL
. I put it here for the namespace.
This was an issue I was about to post a message about.
Currently, if Puma successfully compiles with OpenSSL, it loads all the files. Should we make so that it only loads the files if one binds to an ssl socket?
That is trickier...
README.md
Outdated
@@ -13,11 +13,19 @@ Puma is a **simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server | |||
|
|||
## Built For Speed & Concurrency | |||
|
|||
Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request using a thread pool. Each request is served in a separate thread, so truly concurrent Ruby implementations (JRuby, Rubinius) will use all available CPU cores. | |||
Puma processes requests using a C-optimized Ragel extension (inherited from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you change anything in here other than 80-char line breaks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a sentence to Quick Start, which maybe should be expanded on?
"Puma expects to find OpenSSL development files when installed/compiled. If you want to compile it without ssl support, set ENV['DISABLE_SSL']."
I can pull this and do a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed to format changes and just added an ssl section.
@@ -1,6 +1,7 @@ | |||
## 5.0.0 | |||
|
|||
* Features | |||
* Allow compiling without OpenSSL and dynamically load files needed for SSL, add 'no ssl' CI (#2305) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like for JRuby, for this to work, you need to have DISABLE_SSL set, but for MRI, you don't. Is that true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re MRI, I know how to uninstall 'openssl dev', and it works locally.
I don't know how to uninstall Java's equivalent of 'openssl dev'. For MRI systems, it's a separate install, I don't think that's the case with Java?
EDIT:
Sorry I wasn't clear.
for JRuby, for this to work, you need to have DISABLE_SSL set
Correct.
for MRI, you don't
If you don't have 'openssl dev' installed, there is no need for ENV['DISABLE_SSL']
. If it is installed, you need to set the ENV variable in shell to disable compiling with OpenSSL.
e074cc7
to
5781aab
Compare
Interesting. The last push (which passed CI here) here also ran in my fork. The only failure was on https://github.com/MSP-Greg/puma/runs/1109525323?check_suite_focus=true#step:7:599 Note that the test suite passed, but it just barely timed out, so it shows as a failure. First time I've seen that, but maybe extend the test step's timeout to 12? Hate to do that... |
I noticed that test_puma_server_ssl.rb would not run as a single test file:
Fixed. |
Removed Actions TruffleRuby RuboCop commit |
If the system does not have OpenSSL development files installed, Puma will | ||
install/compile, but it will not allow ssl connections. | ||
|
||
If the system has OpenSSL development files installed, but you don't want Puma |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this is a little unclear. If you don't bind Puma to SSL, why should you need to use DISABLE_SSL
?
As written, this makes it sound like anyone using Puma w/o SSL must set DISABLE_SSL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't bind Puma to SSL, why should you need to use DISABLE_SSL?
You don't have to, but 'If the system has OpenSSL development files', it will compile the SSL functions into puma_http11.so/jar
and will load the OpenSSL libraries/dlls when using MRI. It also loads Ruby OpenSSL on MRI.
I believe using DISABLE_SSL
stops all of that.
this makes it sound like anyone using Puma w/o SSL must set DISABLE_SSL.
Didn't mean to imply that. Maybe a rephrasing is in order. I meant to make it clear that it's optional. But, I didn't say anything about benefits...
BTW, thanks for reviewing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I just ended up removing it. I think it's too confusing. Good feature to have but not one that needs explaining right in README.md.
Thanks so much for your work on the test suite over the last 2 weeks Greg, it's so much better now.
Description
Currently, Puma will not function if built without SSL support. Also, SSL related files are all loaded regardless, so make them load-on-demand.
Changes
Puma::HAS_SSL
orPuma.ssl?
) relies on classes that only exist in the compiled extension if properly compiled with OpenSSL.Commits (need to be squashed for bisect)
'Adjust code for compiling without SSL (MRI & JRuby), add ssl detection' - Removes MiniSSL.check, replace with Puma::HAS_SSL or Puma.ssl?
'Adjust test files for 'no ssl' compile'
'Actions - add 'no ssl' workflow, puma-no-ssl.yml' - three jobs: Ubuntu-20.04 with 2.7 & JRuby, and Windows 2.7
'Update History.md'
'README.md - add 'SSL Connection Support' section'
Your checklist for this pull request
[changelog skip]
the pull request title.[ci skip]
to the title of the PR.#issue
" to the PR description or my commit messages.