Skip to content

Commit

Permalink
Fixes #25293 - Support Puma
Browse files Browse the repository at this point in the history
To support Puma, this takes the approach of introducing a Rack
application that understands the HTTP request scheme. Depending on that,
it responds either with the HTTP or HTTPS app.

This means all the responsibility of binding to HTTP and HTTPS is
shifted to the application server.

To use this:

  bundle exec puma -b tcp://127.0.0.1:8000 -b 'ssl://127.0.0.1:8443?key=config/key.pem&cert=config/cert.pem'

Note that this doesn't set the secure ciphers nor protocols. It also
requires Puma to be built with OpenSSL extensions to be able to bind on
HTTPS.
  • Loading branch information
ekohl committed Oct 2, 2020
1 parent 88fbc8e commit 48f3de3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
8 changes: 5 additions & 3 deletions config.ru
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
$LOAD_PATH.unshift *Dir[File.expand_path('lib', __dir__), File.expand_path('modules', __dir__)]
$LOAD_PATH.unshift(*Dir[File.expand_path('lib', __dir__), File.expand_path('modules', __dir__)])

require 'smart_proxy_main'
::Proxy::PluginInitializer.new(::Proxy::Plugins.instance).initialize_plugins
::Proxy::Plugins.instance.select { |p| p[:state] == :running && p[:https_enabled] }.each { |p| instance_eval(p[:class].https_rackup) }
require 'proxy/app'
plugins = ::Proxy::Plugins.instance
::Proxy::PluginInitializer.new(plugins).initialize_plugins
run ::Proxy::App.new(plugins)
29 changes: 29 additions & 0 deletions lib/proxy/app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Proxy
class App
def initialize(plugins)
@apps = {}

http_plugins = plugins.select { |p| p[:state] == :running && p[:http_enabled] }
if http_plugins.any?
@apps['http'] = Rack::Builder.new do
http_plugins.each { |p| instance_eval(p[:class].http_rackup) }
end
end

https_plugins = plugins.select { |p| p[:state] == :running && p[:https_enabled] }
if https_plugins.any?
@apps['https'] = Rack::Builder.new do
https_plugins.each { |p| instance_eval(p[:class].https_rackup) }
end
end
end

def call(env)
# TODO: Respect X-Forwarded-Proto?
scheme = env['rack.url_scheme']
app = @apps[scheme]
fail "Unsupported URL scheme #{scheme}" unless app
app.call(env)
end
end
end

0 comments on commit 48f3de3

Please sign in to comment.