Ugly Stool Rotating Header Image

January 3rd, 2012:

ruby Sinatra and SSL

I am experimenting with the Google JSON API by writing a back end service.  My intent is to re-use the available client libraries to communicate with my service.  I need to test my implementation, and the mechanics of it all to understand how it works.  I used an existing simple Google service to see how the client would interact with it.

I wanted to mock the Google service quickly, so I started with Sinatra.  I implemented HTTPS support just because – not strictly necessary for this experiment.  I had to hack up the Google service document schema to redirect all URIs from www.googleapis.com to localhost, and I made a few edits to the Google ruby client to override the default port.

The code snippet below creates a self-signed certificate on every start.  I never remember the correct OpenSSL incantation to create a self-signed certificate.  I can find the answer by asking the oracle, but it seems to take a while.  I did not want to have to create another certificate ever again.  By default the auto-generated certificate is good for one year.  (I never expect the service to run for that long.)

Sinatra is configured to response with Hello World! when issuing an HTTP GET request to http://localhost:4567/.  All other HTTP GET requests simply respond with URI requested.  HTTP POST requests echo the data back to the client in the payload.

require 'sinatra/base'
require 'webrick'
require 'webrick/https'
require 'openssl'
name = "/C=US/ST=SomeState/L=SomeCity/O=Organization/OU=Unit/CN=localhost"
ca   = OpenSSL::X509::Name.parse(name)
key = OpenSSL::PKey::RSA.new(1024)
crt = OpenSSL::X509::Certificate.new
crt.version = 2
crt.serial  = 1
crt.subject = ca
crt.issuer = ca
crt.public_key = key.public_key
crt.not_before = Time.now
crt.not_after  = Time.now + 1 * 365 * 24 * 60 * 60 # 1 year
webrick_options = {
    :Port               => 4567,
    :SSLEnable          => true,
    :SSLVerifyClient    => OpenSSL::SSL::VERIFY_NONE,
    :SSLCertificate     => crt,
    :SSLPrivateKey      => key,
    :SSLCertName        => [[ "CN", WEBrick::Utils::getservername ]],
}
def agg_lines(data)
    data.each_line.collect{|x| "  >> #{x}" }.join
end
class MyServer < Sinatra::Base
    get '/' do
        "Hello World!\n"
    end
    get '*' do |x|
        "GET of URI #{x}\n"
    end
    post "*" do |x|
        request.body.rewind
        "POST to URI #{x}\n#{agg_lines(request.body.read)}\n"
    end
end
server = ::Rack::Handler::WEBrick
trap(:INT) do
    server.shutdown
end
server.run(MyServer, webrick_options)

I pieced this script together by crawling StackOverflow posts, and reading documentation.

Page optimized by WP Minify WordPress Plugin