From: John Firebaugh Date: Sat, 20 Oct 2012 23:11:51 +0000 (-0700) Subject: Allow cross-origin requests to API X-Git-Tag: live~5274 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/77519738715b21fbb4ea384c9b56ccc2d9fb4687 Allow cross-origin requests to API --- diff --git a/Gemfile b/Gemfile index fa3f38d79..4644d07ea 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,7 @@ gem 'http_accept_language', '>= 1.0.2' gem 'paperclip', '~> 2.0' gem 'deadlock_retry', '>= 1.2.0' gem 'i18n-js', '>= 3.0.0.rc2' +gem 'rack-cors' # We need ruby-openid 2.2.0 or later for ruby 1.9 support gem 'ruby-openid', '>= 2.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 8c8e60af7..2299757c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -102,6 +102,8 @@ GEM rack (1.4.1) rack-cache (1.2) rack (>= 0.4) + rack-cors (0.2.7) + rack rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) @@ -181,6 +183,7 @@ DEPENDENCIES open_id_authentication (>= 1.1.0) paperclip (~> 2.0) pg + rack-cors rails (= 3.2.8) rails-i18n (>= 0.6.3) redcarpet diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 000000000..6fbeb9161 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,13 @@ +require "rack/cors" + +# Allow any and all cross-origin requests to the API. Allow any origin, and +# any headers. Non-browser requests do not have origin or header restrictions, +# so browser-requests should be similarly permitted. (Though the API does not +# require any custom headers, Ajax frameworks may automatically add headers +# such as X-Requested-By to requests.) +Rails.configuration.middleware.use Rack::Cors do + allow do + origins "*" + resource "/api/*", :headers => :any, :methods => [:get, :post, :put, :delete] + end +end diff --git a/test/integration/cors_test.rb b/test/integration/cors_test.rb new file mode 100644 index 000000000..827db7c93 --- /dev/null +++ b/test/integration/cors_test.rb @@ -0,0 +1,32 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class CORSTest < ActionController::IntegrationTest + # Rails 4 adds a built-in `options` method. When we upgrade, we can remove + # this definition. + unless instance_method_names.include?("options") + def options(*args) + reset! unless integration_session + @html_document = nil + integration_session.send(:process, :options, *args).tap do + copy_session_variables! + end + end + end + + def test_api_routes_allow_cross_origin_requests + options "/api/capabilities", nil, + 'HTTP_ORIGIN' => "http://www.example.com", + 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'GET' + + assert_response :success + assert_equal "http://www.example.com", response.headers['Access-Control-Allow-Origin'] + end + + def test_non_api_routes_dont_allow_cross_origin_requests + assert_raises ActionController::RoutingError do + options "/", nil, + 'HTTP_ORIGIN' => "http://www.example.com", + 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'GET' + end + end +end