Class: Aspera::WebServerSimple

Inherits:
WEBrick::HTTPServer
  • Object
show all
Defined in:
lib/aspera/web_server_simple.rb

Direct Known Subclasses

WebAuth

Constant Summary collapse

CERT_PARAMETERS =
i[key cert chain].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, certificate: nil) ⇒ WebServerSimple

Returns a new instance of WebServerSimple.

Parameters:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/aspera/web_server_simple.rb', line 34

def initialize(uri, certificate: nil)
  # see https://www.rubydoc.info/stdlib/webrick/WEBrick/Config
  webrick_options = {
    BindAddress: uri.host,
    Port:        uri.port,
    Logger:      Log.log,
    AccessLog:   [[self, WEBrick::AccessLog::COMMON_LOG_FORMAT]] # replace default access log to call local method "<<" below
  }
  case uri.scheme
  when 'http'
    Log.log.debug('HTTP mode')
  when 'https'
    webrick_options[:SSLEnable] = true
    if certificate.nil?
      webrick_options[:SSLCertName] = [['CN', WEBrick::Utils.getservername]]
    else
      raise 'certificate must be Hash' unless certificate.is_a?(Hash)
      certificate = certificate.symbolize_keys
      raise "unexpected key in certificate config: only: #{CERT_PARAMETERS.join(', ')}" if certificate.keys.any?{|k|!CERT_PARAMETERS.include?(k)}
      webrick_options[:SSLPrivateKey] = if certificate.key?(:key)
        OpenSSL::PKey::RSA.new(File.read(certificate[:key]))
      else
        OpenSSL::PKey::RSA.new(4096)
      end
      if certificate.key?(:cert)
        webrick_options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(certificate[:cert]))
      else
        webrick_options[:SSLCertificate] = OpenSSL::X509::Certificate.new
        self.class.fill_self_signed_cert(webrick_options[:SSLCertificate], webrick_options[:SSLPrivateKey])
      end
      if certificate.key?(:chain)
        webrick_options[:SSLExtraChainCert] = [OpenSSL::X509::Certificate.new(File.read(certificate[:chain]))]
      end
    end
  end
  # self signed certificate generates characters on STDERR, see create_self_signed_cert in webrick/ssl.rb
  Log.capture_stderr { super(webrick_options) }
  # kill -USR1 for graceful shutdown
  Kernel.trap('USR1') { shutdown }
end

Class Method Details

.fill_self_signed_cert(cert, key) ⇒ Object

generates and adds self signed cert to provided webrick options



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/aspera/web_server_simple.rb', line 13

def fill_self_signed_cert(cert, key)
  cert.subject = cert.issuer = OpenSSL::X509::Name.parse('/C=FR/O=Test/OU=Test/CN=Test')
  cert.not_before = Time.now
  cert.not_after = Time.now + 365 * 24 * 60 * 60
  cert.public_key = key.public_key
  cert.serial = 0x0
  cert.version = 2
  ef = OpenSSL::X509::ExtensionFactory.new
  ef.issuer_certificate = cert
  ef.subject_certificate = cert
  cert.extensions = [
    ef.create_extension('basicConstraints', 'CA:TRUE', true),
    ef.create_extension('subjectKeyIdentifier', 'hash')
    # ef.create_extension('keyUsage', 'cRLSign,keyCertSign', true),
  ]
  cert.add_extension(ef.create_extension('authorityKeyIdentifier', 'keyid:always,issuer:always'))
  cert.sign(key, OpenSSL::Digest.new('SHA256'))
end

Instance Method Details

#<<(access_log) ⇒ Object

log web server access ( option AccessLog )



76
77
78
# File 'lib/aspera/web_server_simple.rb', line 76

def <<(access_log)
  Log.log.debug{"webrick log #{access_log.chomp}"}
end