class Rack::BodyParser

BodyParser implementation.

Constants

ERROR_HANDLER
ERROR_MESSAGE

Default error handler

HANDLERS
RACK_ENV_KEY

Where to store in env

RACK_REQUEST_KEY

Where to store in Rack::Request in case of opts

REQUEST_BODY

Where to get input.

VERSION

Attributes

handlers[R]
logger[R]
parsers[R]

Public Class Methods

new(app, opts = {}) click to toggle source
# File lib/rack/bodyparser.rb, line 22
def initialize(app, opts = {})
  @app      = app
  @parsers  = opts.delete(:parsers) || {}
  @handlers = HANDLERS.merge(opts.delete(:handlers) || {})
  @logger   = opts.delete(:logger)
  @opts     = opts
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack/bodyparser.rb, line 30
def call(env)
  type   = Rack::Request.new(env).media_type
  parser = type && detect(parsers, type)

  if parser
    begin
      parse_with(parser.last, env) # parser.last is actual parser
    rescue StandardError => e
      return handle_error(e, type) # return error response
    end
  end

  # return control to app
  @app.call env
end
detect(hash, what) click to toggle source

returns [type, parser]

# File lib/rack/bodyparser.rb, line 80
def detect(hash, what)
  hash.detect do |match, _|
    match.is_a?(Regexp) ? what.match(match) : what.eql?(match)
  end
end
handle_error(e, type) click to toggle source
# File lib/rack/bodyparser.rb, line 68
def handle_error(e, type)
  warn!(e, type)
  handler = (detect(handlers, type) || detect(handlers, 'default')).last
  handler.call(e, type)
end
parse_with(parser, env) click to toggle source
# File lib/rack/bodyparser.rb, line 53
def parse_with(parser, env)
  body = request_body(env)
  return unless body && !body.empty?

  # Give env to parser if it has a setter for it.
  parser.env = env if parser.respond_to? :env=

  # parse!
  parsed = parser.call(body)

  # store results in env, optionally in Rack::Request.
  env.update(RACK_ENV_KEY => parsed)
  patch_rack_request(parser, parsed) if @opts[:patch_request]
end
patch_rack_request(parser, parsed) click to toggle source
# File lib/rack/bodyparser.rb, line 74
def patch_rack_request(parser, parsed)
  return unless parser.respond_to?(:rack_request_key)
  Rack::Request.send(:define_method, parser.rack_request_key) { parsed }
end
request_body(env) click to toggle source
# File lib/rack/bodyparser.rb, line 46
def request_body(env)
  body = env[REQUEST_BODY].read
  env[REQUEST_BODY].rewind

  body
end
warn!(e, type) click to toggle source
# File lib/rack/bodyparser.rb, line 86
def warn!(e, type)
  return unless logger
  logger.warn format(ERROR_MESSAGE, type, e.to_s)
end