Sha256: 59fe062a697caf6698b8e531c7c9db20794c53d75a509a9e71eae37a0d55cd67

Contents?: true

Size: 1.19 KB

Versions: 5

Compression:

Stored size: 1.19 KB

Contents

begin
  require 'json'
rescue LoadError => e
  require 'json/pure'
end

module Rack

  # A Rack middleware for parsing POST/PUT body data when Content-Type is
  # not one of the standard supported types, like <tt>application/json</tt>.
  #
  # TODO: Find a better name.
  #
  class PostBodyContentTypeParser

    # Constants
    #
    CONTENT_TYPE = 'CONTENT_TYPE'.freeze
    POST_BODY = 'rack.input'.freeze
    FORM_INPUT = 'rack.request.form_input'.freeze
    FORM_HASH = 'rack.request.form_hash'.freeze

    # Supported Content-Types
    #
    APPLICATION_JSON = 'application/json'.freeze

    def initialize(app)
      @app = app
    end

    def call(env)
      if Rack::Request.new(env).media_type == APPLICATION_JSON && (body = env[POST_BODY].read).length != 0
        env[POST_BODY].rewind # somebody might try to read this stream
        env.update(FORM_HASH => JSON.parse(body, :create_additions => false), FORM_INPUT => env[POST_BODY])
      end
      @app.call(env)
    rescue JSON::ParserError
      bad_request('failed to parse body as JSON')
    end

    def bad_request(body = 'Bad Request')
      [ 400, { 'Content-Type' => 'text/plain', 'Content-Length' => body.size.to_s }, [body] ]
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
rack-contrib-2.0.1 lib/rack/contrib/post_body_content_type_parser.rb
rack-contrib-2.0.0 lib/rack/contrib/post_body_content_type_parser.rb
rack-contrib-1.8.0 lib/rack/contrib/post_body_content_type_parser.rb
rack-contrib-1.7.0 lib/rack/contrib/post_body_content_type_parser.rb
rack-contrib-1.6.0 lib/rack/contrib/post_body_content_type_parser.rb