Skip to content

Commit

Permalink
Merge pull request cyu#1 from dipspb/master
Browse files Browse the repository at this point in the history
pulled in Access-Control-Expose-Headers, X-Origin and Regex origin changes from dipspb
  • Loading branch information
cyu committed Jun 4, 2011
2 parents 4cf25de + 02297d0 commit 5849b99
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
8 changes: 6 additions & 2 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ You configure Rack::Cors by passing a block to the <tt>use</tt> command:

use Rack::Cors do |cfg|
cfg.allow do |allow|
allow.origins 'localhost:3000', '127.0.0.1:3000'
allow.origins 'localhost:3000', '127.0.0.1:3000',
/http:\/\/192\.168\.0\.\d{1,3}(:\d+)?/
# regular expressions can be used here

allow.resource '/file/list_all/', :headers => 'x-domain-token'
allow.resource '/file/at/*',
:methods => [:get, :post, :put, :delete],
:headers => 'x-domain-token'
:headers => 'x-domain-token',
:expose => ['Some-Custom-Response-Header']
# headers to expose
end

cfg.allow do |allow|
Expand Down
35 changes: 28 additions & 7 deletions lib/rack/cors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ def allow
end

def call(env)
if env['HTTP_ORIGIN'] == 'null'
env['HTTP_ORIGIN'] = 'file://'
end
if env['HTTP_X_ORIGIN'] and not env['HTTP_ORIGIN']
puts 'ORIGIN header is empty, X-ORIGIN workaround header applied.'
env['HTTP_ORIGIN'] = env['HTTP_X_ORIGIN']
end
cors_headers = nil
if env['HTTP_ORIGIN']
debug(env) do
Expand Down Expand Up @@ -76,13 +83,17 @@ def initialize

def origins(*args)
@origins = args.flatten.collect do |n|
case n
when /^https?:\/\// then n
when '*'
@public_resources = true
if n.class == Regexp
n
else
"http://#{n}"
case n
when /^https?:\/\// then n
when '*'
@public_resources = true
n
else
"http://#{n}"
end
end
end
end
Expand All @@ -96,7 +107,9 @@ def public_resources?
end

def allow_origin?(source)
public_resources? || @origins.include?(source)
result = public_resources? || @origins.include?(source) ||
(not (@origins.select {|n| n.class == Regexp && n.match(source)}).empty?)
result
end

def find_resource(path)
Expand All @@ -105,7 +118,7 @@ def find_resource(path)
end

class Resource
attr_accessor :path, :methods, :headers, :max_age, :credentials, :pattern
attr_accessor :path, :methods, :headers, :expose, :max_age, :credentials, :pattern

def initialize(public_resource, path, opts={})
self.path = path
Expand All @@ -121,6 +134,12 @@ def initialize(public_resource, path, opts={})
else
[opts[:headers]].flatten.collect{|h| h.downcase}
end

self.expose = case opts[:expose]
when nil then nil
else
[opts[:expose]].flatten
end
end

def match?(path)
Expand All @@ -133,8 +152,10 @@ def process_preflight(env)
end

def to_headers(env)
x_origin = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
h = { 'Access-Control-Allow-Origin' => public_resource? ? '*' : env['HTTP_ORIGIN'],
'Access-Control-Allow-Methods' => methods.collect{|m| m.to_s.upcase}.join(', '),
'Access-Control-Expose-Headers' => expose.nil? ? '' : expose.join(', '),
'Access-Control-Max-Age' => max_age.to_s }
h['Access-Control-Allow-Credentials'] = 'true' if credentials
h
Expand Down

0 comments on commit 5849b99

Please sign in to comment.