class Rack::Csrf

def self.field

def self.field
  @@field
end

def self.header

def self.header
  @@header
end

def self.key

def self.key
  @@key
end

def self.metatag(env, options = {})

def self.metatag(env, options = {})
  name = options.fetch(:name, '_csrf')
  %Q(<meta name="#{name}" content="#{token(env)}" />)
end

def self.rackified_header

Returns the custom header's name adapted to current standards.
def self.rackified_header
  "HTTP_#{@@header.gsub('-', '_').upcase}"
end

def self.tag(env)

def self.tag(env)
  %Q(<input type="hidden" name="#{field}" value="#{token(env)}" />)
end

def self.token(env)

def self.token(env)
  env['rack.session'][key] ||= SecureRandom.urlsafe_base64(32)
end

def any? list, request

Returns +true+ when the given list "includes" the request.
def any? list, request
  pi = request.path_info.empty? ? '/' : request.path_info
  list.any? do |route|
    route =~ (request.request_method + ':' + pi)
  end
end

def call(env)

def call(env)
  unless env['rack.session']
    fail SessionUnavailable, 'Rack::Csrf depends on session middleware'
  end
  req = Rack::Request.new(env)
  let_it_pass = skip_checking(req) ||
    !@http_methods.include?(req.request_method) ||
    found_a_valid_token?(req)
  if let_it_pass
    @app.call(env)
  else
    fail InvalidCsrfToken if @raise_if_invalid
    [403, {CONTENT_TYPE => 'text/html', CONTENT_LENGTH => '0'}, []]
  end
end

def found_a_valid_token? request

def found_a_valid_token? request
  token = self.class.token(request.env)
  Rack::Utils.secure_compare(request.params[self.class.field].to_s, token) ||
    Rack::Utils.secure_compare(request.env[self.class.rackified_header].to_s, token)
end

def initialize(app, opts = {})

def initialize(app, opts = {})
  @app = app
  @raise_if_invalid = opts.fetch(:raise, false)
  @skip_list        = opts.fetch(:skip, []).map {|r| /\A#{r}\Z/i}
  @skip_if          = opts[:skip_if]
  @check_only_list  = opts.fetch(:check_only, []).map {|r| /\A#{r}\Z/i}
  @@field           = opts[:field] if opts[:field]
  @@header          = opts[:header] if opts[:header]
  @@key             = opts[:key] if opts[:key]
  standard_http_methods = %w(POST PUT DELETE PATCH)
  check_also            = opts.fetch(:check_also, [])
  @http_methods = (standard_http_methods + check_also).flatten.uniq
end

def skip_checking request

check only list.
triggered by the +check_only+ option), it does not appear in the
only list is not empty (i.e., we are working in the "reverse mode"
the conditional skipping code return true or, when the check
Returns +true+ if the given request appears in the skip list or
def skip_checking request
  to_be_skipped = any? @skip_list, request
  to_be_skipped ||= @skip_if && @skip_if.call(request)
  to_be_checked = any? @check_only_list, request
  to_be_skipped || (!@check_only_list.empty? && !to_be_checked)
end