Forcing SSL in a Sinatra App

When deploying on Heroku, you can piggy back on their SSL certificate, which allows you to have a secure connection right away without any SSL configurations of your own. I think this is a great solution for a lot of people until you need a really pretty URL. Because this is possible, you should use it, and if your building an API you should also think about forcing different environments to require SSL. Here is a simple implementation in my `app.rb` file:

class Myapi < Sinatra::Application
  ActiveRecord::Base.default_timezone = :utc

  configure :development, :test do
    set :host, 'localhost:9999'
    set :force_ssl, false
  end
  configure :staging do
    set :host, 'my-api-staging.herokuapp.com'
    set :force_ssl, true
  end
  configure :production do
    set :host, 'my-api.herokuapp.com'
    set :force_ssl, true
  end

  before do
    content_type :json
    ssl_whitelist = ['/calendar.ics']
    if settings.force_ssl && !request.secure? && !ssl_whitelist.include?(request.path_info)
      halt json_status 400, "Please use SSL at https://#{settings.host}"
    end
  end
end

require_relative 'application/helpers/init'
require_relative 'application/routes/init'
require_relative 'application/models/init'
require_relative 'application/core_extensions/init'

I have left some of my app-specific code in there as well, but I am sure you can dig around that to see how SSL is forced. Notice that because downloading `.ics` files shouldn’t require SSL, or in other words, it shouldn’t fail if the user uses `http`, it is included in a whitelist array.