Search code examples
rubysslsinatrawebrick

How to enable SSL for a standalone Sinatra app?


I want to write a quick server app in Sinatra. It has to be self-contained (i.e. not use apache/nginx/passenger) but also has to support SSL.

Is there an easy way to enable SSL support for Sinatra (using WEBRick for example)?


Solution

  • To do this with MRI ruby, use the following monkeypatch:

    sinatra_ssl.rb:

    require 'webrick/https'
    
    module Sinatra
      class Application
        def self.run!
          certificate_content = File.open(ssl_certificate).read
          key_content = File.open(ssl_key).read
    
          server_options = {
            :Host => bind,
            :Port => port,
            :SSLEnable => true,
            :SSLCertificate => OpenSSL::X509::Certificate.new(certificate_content),
            :SSLPrivateKey => OpenSSL::PKey::RSA.new(key_content)
          }
    
          Rack::Handler::WEBrick.run self, server_options do |server|
            [:INT, :TERM].each { |sig| trap(sig) { server.stop } }
            server.threaded = settings.threaded if server.respond_to? :threaded=
            set :running, true
          end
        end
      end
    end
    

    Then, in your standalone application:

    app.rb

    require 'sinatra'
    require 'sinatra_ssl'
    
    set :port, 8443
    set :ssl_certificate, "server.crt"
    set :ssl_key, "server.key"
    
    get "/" do
      "Hello world!"
    end