Implement Cross-Origin Resource Sharing:
* Add Api::ApplicationController * Route OPTION requests (CORS preflight) to API application controller * Filter all API requests through #cor_filter in API application controller
This commit is contained in:
parent
88d3242843
commit
6379da88e2
14
app/controllers/api/application_controller.rb
Normal file
14
app/controllers/api/application_controller.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Api::ApplicationController < ApplicationController
|
||||||
|
before_filter :cor_filter
|
||||||
|
|
||||||
|
def cor_filter
|
||||||
|
headers['Access-Control-Allow-Origin'] = request.headers['Origin']
|
||||||
|
end
|
||||||
|
|
||||||
|
def cor_preflight
|
||||||
|
headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
|
||||||
|
headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Requested-With'
|
||||||
|
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
@ -1,4 +1,4 @@
|
|||||||
class Api::V0::PlaylistsController < ApplicationController
|
class Api::V0::PlaylistsController < Api::ApplicationController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -3,6 +3,8 @@ Scube::Application.routes.draw do
|
|||||||
namespace :v0 do
|
namespace :v0 do
|
||||||
resources :playlists, :only => [:index]
|
resources :playlists, :only => [:index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
match '*all' => 'application#cor_preflight', :via => :options
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :sounds, :only => [:show]
|
resources :sounds, :only => [:show]
|
||||||
|
49
spec/controllers/api/application_controller_spec.rb
Normal file
49
spec/controllers/api/application_controller_spec.rb
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Api::ApplicationController do
|
||||||
|
before do
|
||||||
|
controller.current_user = Factory.create(:user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'CORS: Cross-Origin Ressource Sharing' do
|
||||||
|
before do
|
||||||
|
request.env['Origin'] = 'http://origin.example/'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'preflight' do
|
||||||
|
controller(Api::ApplicationController) do
|
||||||
|
alias_method :index, :cor_preflight
|
||||||
|
end
|
||||||
|
|
||||||
|
def options(action)
|
||||||
|
process action, nil, nil, nil, 'OPTIONS'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Methods header' do
|
||||||
|
options :index
|
||||||
|
response.headers['Access-Control-Allow-Methods'].should ==
|
||||||
|
'GET, POST, PUT, DELETE'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Methods header' do
|
||||||
|
options :index
|
||||||
|
response.headers['Access-Control-Allow-Headers'].should ==
|
||||||
|
'Content-Type, X-Requested-With'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'before filter' do
|
||||||
|
controller(Api::ApplicationController) do
|
||||||
|
def index
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Origin header' do
|
||||||
|
get :index
|
||||||
|
response.headers['Access-Control-Allow-Origin'].should ==
|
||||||
|
request.env['Origin']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
41
spec/integration/api/cross_origin_request_spec.rb
Normal file
41
spec/integration/api/cross_origin_request_spec.rb
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature 'API cross origin request' do
|
||||||
|
include UserIntegrationHelpers
|
||||||
|
|
||||||
|
let(:user) { Factory.create(:user) }
|
||||||
|
let(:origin) { 'http://origin.example/' }
|
||||||
|
|
||||||
|
background do
|
||||||
|
post sessions_path, :session => {
|
||||||
|
:email => user.email,
|
||||||
|
:password => user.password
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'preflight request' do
|
||||||
|
# FIXME: replace with a more stable/generic action
|
||||||
|
# FIXME: request without redirect
|
||||||
|
request_via_redirect(
|
||||||
|
:options,
|
||||||
|
api_v0_playlists_path(:format => :json),
|
||||||
|
nil,
|
||||||
|
{ 'Origin' => origin }
|
||||||
|
)
|
||||||
|
|
||||||
|
response.headers['Access-Control-Allow-Origin'].should == origin
|
||||||
|
response.headers['Access-Control-Allow-Methods'].should ==
|
||||||
|
'GET, POST, PUT, DELETE'
|
||||||
|
response.headers['Access-Control-Allow-Headers'].should ==
|
||||||
|
'Content-Type, X-Requested-With'
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'basic request' do
|
||||||
|
# FIXME: replace with a more stable/generic action
|
||||||
|
get api_v0_playlists_path(:format => :json), nil, {
|
||||||
|
'Origin' => origin
|
||||||
|
}
|
||||||
|
|
||||||
|
response.headers['Access-Control-Allow-Origin'].should == origin
|
||||||
|
end
|
||||||
|
end
|
11
spec/routing/options_requests_spec.rb
Normal file
11
spec/routing/options_requests_spec.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe '/api OPTIONS requests routing' do
|
||||||
|
it 'routes to Api::ApplicationController#cor_preflight' do
|
||||||
|
{ :options => '/api/v0' }.should route_to(
|
||||||
|
:controller => 'api/application',
|
||||||
|
:action => 'cor_preflight',
|
||||||
|
:all => 'v0'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user