Search code examples
rubycorsrackpumaresponse-headers

Passing headers (or other settings) from Sinatra through Puma


I am trying to learn how to develop a simple web app using pure Ruby. I have a simple backend service which I created as a Sinatra app. While developing it, I noticed the frontend (a simple HTML/JS static site) would not communicate with it because of CORS policies. So I looked into how to pass headers from Sinatra.

I came across sinatra-cors. I set it up as instructed and my app looks like this (abbreviated):

require 'sinatra'
require 'sinatra/cors'

  set :allow_origin, '*'
  set :allow_methods, 'GET,HEAD,POST'
  set :allow_headers, 'content-type,if-modified-since,access-control-allow-methods,access-control-allow-origin'
  set :expose_headers, 'content-disposition'
  set :allow_credentials, true

  post '/' do
    [...]
  end

When I run it with ruby app.rb, it works perfectly. Frontend can communicate and CORS policies are observed.

Now, I want to set up the service for a production environment. For that, I want to use Puma. So with Puma, I have a config.ru which looks like this:

require File.expand_path('app', File.dirname(__FILE__))
run WebApp

and I modified my app.rb to look like this (again abbreviated):

require 'sinatra'
require 'sinatra/cors'

class WebApp < Sinatra::Application

  set :allow_origin, '*'
  set :allow_methods, 'GET,HEAD,POST'
  set :allow_headers, 'content-type,if-modified-since,access-control-allow-methods,access-control-allow-origin'
  set :expose_headers, 'content-disposition'
  set :allow_credentials, true

  post '/' do
    [...]
  end
end

basically, wrapped the app in a class, and call it from the config.ru. When I run this by running puma in the directory, the service comes up, but headers are no longer passed back. Whenever I try to hit the backend, I get:

Access to XMLHttpRequest at 'http://localhost:4567/' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This was the error I was getting before I originally set up the headers. So it seems pretty clear to me that the set parameters are being ignored.

So, this seems like a simple matter, but I have not been able to find a proper answer: How do I make Puma respect the 'set' parameters? Or alternatively, how do I achieve the same desired result?

It seems clear to me that I am missing a very simple thing, but I cannot figure out what exactly it is.

Thanks in advance!


Solution

  • It looks like you are just missing register Sinatra::Cors in your class.

    class WebApp < Sinatra::Application
      register Sinatra::Cors # Add this line.
    
      set :allow_origin, '*'
      # etc.