class Rack::Cors::Resource

Attributes

credentials[RW]
expose[RW]
headers[RW]
if_proc[RW]
max_age[RW]
methods[RW]
path[RW]
pattern[RW]
vary_headers[RW]

Public Class Methods

new(public_resource, path, opts={}) click to toggle source
# File lib/rack/cors.rb, line 326
def initialize(public_resource, path, opts={})
  raise CorsMisconfigurationError if public_resource && opts[:credentials] == true

  self.path         = path
  self.credentials  = public_resource ? false : (opts[:credentials] == true)
  self.max_age      = opts[:max_age] || 1728000
  self.pattern      = compile(path)
  self.if_proc      = opts[:if]
  self.vary_headers = opts[:vary] && [opts[:vary]].flatten
  @public_resource  = public_resource

  self.headers = case opts[:headers]
  when :any then :any
  when nil then nil
  else
    [opts[:headers]].flatten.collect{|h| h.downcase}
  end

  self.methods = case opts[:methods]
  when :any then [:get, :head, :post, :put, :patch, :delete, :options]
  else
    ensure_enum(opts[:methods]) || [:get]
  end.map{|e| e.to_s }

  self.expose = opts[:expose] ? [opts[:expose]].flatten : nil
end

Public Instance Methods

match?(path, env) click to toggle source
# File lib/rack/cors.rb, line 357
def match?(path, env)
  matches_path?(path) && (if_proc.nil? || if_proc.call(env))
end
matches_path?(path) click to toggle source
# File lib/rack/cors.rb, line 353
def matches_path?(path)
  pattern =~ path
end
process_preflight(env, result) click to toggle source
# File lib/rack/cors.rb, line 361
def process_preflight(env, result)
  headers = {CONTENT_TYPE => TEXT_PLAIN}

  request_method = env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]
  if request_method.nil?
    result.miss(Result::MISS_NO_METHOD) and return headers
  end
  if !methods.include?(request_method.downcase)
    result.miss(Result::MISS_DENY_METHOD) and return headers
  end

  request_headers = env[HTTP_ACCESS_CONTROL_REQUEST_HEADERS]
  if request_headers && !allow_headers?(request_headers)
    result.miss(Result::MISS_DENY_HEADER) and return headers
  end

  result.hit = true
  headers.merge(to_preflight_headers(env))
end
to_headers(env) click to toggle source
# File lib/rack/cors.rb, line 381
def to_headers(env)
  h = {
    'Access-Control-Allow-Origin'     => origin_for_response_header(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
end

Protected Instance Methods

allow_headers?(request_headers) click to toggle source
# File lib/rack/cors.rb, line 409
def allow_headers?(request_headers)
  return false if headers.nil?
  headers == :any || begin
    request_headers = request_headers.split(/,\s*/) if request_headers.kind_of?(String)
    request_headers.all?{|h| headers.include?(h.downcase)}
  end
end
compile(path) click to toggle source
# File lib/rack/cors.rb, line 422
def compile(path)
  if path.respond_to? :to_str
    special_chars = %w{. + ( )}
    pattern =
      path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
        case match
        when "*"
          "(.*?)"
        when *special_chars
          Regexp.escape(match)
        else
          "([^/?&#]+)"
        end
      end
    /^#{pattern}$/
  elsif path.respond_to? :match
    path
  else
    raise TypeError, path
  end
end
ensure_enum(v) click to toggle source
# File lib/rack/cors.rb, line 417
def ensure_enum(v)
  return nil if v.nil?
  [v].flatten
end
origin_for_response_header(origin) click to toggle source
# File lib/rack/cors.rb, line 396
def origin_for_response_header(origin)
  return '*' if public_resource?
  origin
end
public_resource?() click to toggle source
# File lib/rack/cors.rb, line 392
def public_resource?
  @public_resource
end
to_preflight_headers(env) click to toggle source
# File lib/rack/cors.rb, line 401
def to_preflight_headers(env)
  h = to_headers(env)
  if env[HTTP_ACCESS_CONTROL_REQUEST_HEADERS]
    h.merge!('Access-Control-Allow-Headers' => env[HTTP_ACCESS_CONTROL_REQUEST_HEADERS])
  end
  h
end