Class: Aspera::WebServerSimple
- Inherits:
-
WEBrick::HTTPServer
- Object
- WEBrick::HTTPServer
- Aspera::WebServerSimple
- Defined in:
- lib/aspera/web_server_simple.rb
Overview
Simple WEBrick server with HTTPS support
Direct Known Subclasses
Constant Summary collapse
- PARAMS =
%i[cert key chain].freeze
- DEFAULT_URL =
'http://localhost:8080'
Class Method Summary collapse
-
.read_chain_file(chain) ⇒ Object
A list of Certificates from chain file.
-
.self_signed_cert(private_key, digest: 'SHA256') ⇒ Object
Generate or fill and self sign certificate.
Instance Method Summary collapse
-
#<<(access_log) ⇒ Object
log web server access ( option AccessLog ).
-
#initialize(uri, cert: nil, key: nil, chain: nil) ⇒ WebServerSimple
constructor
A new instance of WebServerSimple.
-
#start ⇒ Object
blocking.
Constructor Details
#initialize(uri, cert: nil, key: nil, chain: nil) ⇒ WebServerSimple
Returns a new instance of WebServerSimple.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/aspera/web_server_simple.rb', line 55 def initialize(uri, cert: nil, key: nil, chain: nil) Aspera.assert_type(uri, URI) @uri = uri # see https://www.rubydoc.info/stdlib/webrick/WEBrick/Config = { 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' [:SSLEnable] = true if cert.nil? && key.nil? [:SSLCertName] = [['CN', WEBrick::Utils.getservername]] elsif cert && PKCS12_EXT.include?(File.extname(cert).downcase) # PKCS12 Log.log.debug('Using PKCS12 certificate') raise 'PKCS12 requires a key (password)' if key.nil? pkcs12 = OpenSSL::PKCS12.new(File.read(cert), key) [:SSLCertificate] = pkcs12.certificate [:SSLPrivateKey] = pkcs12.key [:SSLExtraChainCert] = pkcs12.ca_certs else Log.log.debug('Using PEM certificate') [:SSLPrivateKey] = if key.nil? OpenSSL::PKey::RSA.new(4096) else OpenSSL::PKey::RSA.new(File.read(key)) end [:SSLCertificate] = if cert.nil? self.class.self_signed_cert([:SSLPrivateKey]) else OpenSSL::X509::Certificate.new(File.read(cert)) end [:SSLExtraChainCert] = read_chain_file(chain) unless chain.nil? raise 'key and cert do not match' unless [:SSLCertificate].public_key.to_der == [:SSLPrivateKey].public_key.to_der end end # call constructor of parent class, but capture STDERR # self signed certificate generates characters on STDERR # see create_self_signed_cert in webrick/ssl.rb Log.capture_stderr{super()} end |
Class Method Details
.read_chain_file(chain) ⇒ Object
Returns a list of Certificates from chain file.
46 47 48 |
# File 'lib/aspera/web_server_simple.rb', line 46 def read_chain_file(chain) File.read(chain).scan(/-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m).map{ |i| OpenSSL::X509::Certificate.new(i)} end |
.self_signed_cert(private_key, digest: 'SHA256') ⇒ Object
Generate or fill and self sign certificate
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/aspera/web_server_simple.rb', line 24 def self_signed_cert(private_key, digest: 'SHA256') cert = OpenSSL::X509::Certificate.new cert.subject = cert.issuer = OpenSSL::X509::Name.parse(GENERIC_ISSUER) cert.not_before = Time.now - CLOCK_SKEW_OFFSET_SEC cert.not_after = cert.not_before + ONE_YEAR_SECONDS cert.public_key = private_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(private_key, OpenSSL::Digest.new(digest)) cert end |