auto-generate Unicorn::Const::UNICORN_VERSION
[unicorn.git] / lib / unicorn / ssl_server.rb
blobc00c3aef4c5e0fa20da9f3c54e90e37ed2490049
1 # -*- encoding: binary -*-
2 # :stopdoc:
3 # this module is meant to be included in Unicorn::HttpServer
4 # It is an implementation detail and NOT meant for users.
5 module Unicorn::SSLServer
6   attr_accessor :ssl_engine
8   def ssl_enable!
9     sni_hostnames = rack_sni_hostnames(@app)
10     seen = {} # we map a single SSLContext to multiple listeners
11     listener_ctx = {}
12     @listener_opts.each do |address, address_opts|
13       ssl_opts = address_opts[:ssl_opts] or next
14       listener_ctx[address] = seen[ssl_opts.object_id] ||= begin
15         unless sni_hostnames.empty?
16           ssl_opts = ssl_opts.dup
17           ssl_opts[:sni_hostnames] = sni_hostnames
18         end
19         ctx = Flipper.ssl_context(ssl_opts)
20         # FIXME: make configurable
21         ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF
22         ctx
23       end
24     end
25     Unicorn::HttpServer::LISTENERS.each do |listener|
26       ctx = listener_ctx[sock_name(listener)] or next
27       listener.extend(Kgio::SSLServer)
28       listener.ssl_ctx = ctx
29       listener.kgio_ssl_class = Unicorn::SSLClient
30     end
31   end
33   # ugh, this depends on Rack internals...
34   def rack_sni_hostnames(rack_app) # :nodoc:
35     hostnames = {}
36     if Rack::URLMap === rack_app
37       mapping = rack_app.instance_variable_get(:@mapping)
38       mapping.each { |hostname,_,_,_| hostnames[hostname] = true }
39     end
40     hostnames.keys
41   end
42 end