unicorn.git  about / heads / tags
Rack HTTP server for Unix and fast clients
blob c00c3aef4c5e0fa20da9f3c54e90e37ed2490049 1391 bytes (raw)
$ git show httpdate-nogvl:lib/unicorn/ssl_server.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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

git clone https://yhbt.net/unicorn.git