diff options
Diffstat (limited to 'lib/unicorn/ssl_server.rb')
-rw-r--r-- | lib/unicorn/ssl_server.rb | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/unicorn/ssl_server.rb b/lib/unicorn/ssl_server.rb new file mode 100644 index 0000000..c00c3ae --- /dev/null +++ b/lib/unicorn/ssl_server.rb @@ -0,0 +1,42 @@ +# -*- encoding: binary -*- +# :stopdoc: +# this module is meant to be included in Unicorn::HttpServer +# It is an implementation detail and NOT meant for users. +module Unicorn::SSLServer + attr_accessor :ssl_engine + + def ssl_enable! + sni_hostnames = rack_sni_hostnames(@app) + seen = {} # we map a single SSLContext to multiple listeners + listener_ctx = {} + @listener_opts.each do |address, address_opts| + ssl_opts = address_opts[:ssl_opts] or next + listener_ctx[address] = seen[ssl_opts.object_id] ||= begin + unless sni_hostnames.empty? + ssl_opts = ssl_opts.dup + ssl_opts[:sni_hostnames] = sni_hostnames + end + ctx = Flipper.ssl_context(ssl_opts) + # FIXME: make configurable + ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF + ctx + end + end + Unicorn::HttpServer::LISTENERS.each do |listener| + ctx = listener_ctx[sock_name(listener)] or next + listener.extend(Kgio::SSLServer) + listener.ssl_ctx = ctx + listener.kgio_ssl_class = Unicorn::SSLClient + end + end + + # ugh, this depends on Rack internals... + def rack_sni_hostnames(rack_app) # :nodoc: + hostnames = {} + if Rack::URLMap === rack_app + mapping = rack_app.instance_variable_get(:@mapping) + mapping.each { |hostname,_,_,_| hostnames[hostname] = true } + end + hostnames.keys + end +end |