diff options
author | Eric Wong <normalperson@yhbt.net> | 2011-09-07 00:36:58 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-09-15 21:37:40 +0000 |
commit | ac346b5abcfa6253bd792091e5fb011774c40d49 (patch) | |
tree | b304b96f42c3ba2cde396de8ed626754ae9d78cc /lib/unicorn/ssl_server.rb | |
parent | b48c6659b294b37f2c6ff3e75c1c9245522d48d1 (diff) | |
download | unicorn-ac346b5abcfa6253bd792091e5fb011774c40d49.tar.gz |
This will also be the foundation of SSL support in Rainbows! and Zbatery. Some users may also want to use this in Unicorn on LANs to meet certain security/auditing requirements. Of course, Nightmare! (in whatever form) should also be able to use it.
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 |