Tuesday, December 16, 2014

Rails force_ssl causing NginX infinite loop

Today I was configuring some new security features on one of my employers websites. One of them was feature to always force ssl on application.
In Rails 3.2.x and 4.x you can do that by just using force_ssl in Controller or in config/enviroment/production.rbMore info
Everything worked nice then I deployed to Staging and my server neded up in relally dumb infinite loop:
# log/staging.log
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Turns out that NginX needs to pass X-Forwarded-Proto header so that Rails recognize that "yes I'm on ssl"
# /etc/nginx/nginx.conf  # ..or one of your sites-enabled


  # ...
  location @unicorn {
    # ...
    proxy_set_header X-Forwarded-Proto https;
    # ...
    proxy_pass http://unicorn;
  }
source:

Friday, December 12, 2014

change Rack Test default host

If you're using Rack Test to test requests on your Sinatra application you will notice that by default the host isexample.org.
you can change this like this:
# spec/spec_helper.rb
def app
  MySinatraOrRackApp
end

module Rack
  module Test
    module Methods
      def build_rack_mock_session
        Rack::MockSession.new(app, 'api.myapp.com')
      end
    end
  end
end

# this has to be done before you do  `include Rack::Test::Methods`
note: Rack Test is the lib that is repsonsible for request test, so when you do post('/events')get('/', token: 123), ...

source: