Sha256: 92dabe4f84431483e15a4ec38b3ce4bd448345fd4484e7edf7a464110babeacb

Contents?: true

Size: 1.87 KB

Versions: 11

Compression:

Stored size: 1.87 KB

Contents

# frozen_string_literal: true

require "hanami/router/params"
require "hanami/middleware/error"
require_relative "../router/constants"

module Hanami
  module Middleware
    # @since 1.3.0
    # @api private
    class BodyParser
      require_relative "body_parser/class_interface"
      require_relative "body_parser/parser"

      # @since 1.3.0
      # @api private
      CONTENT_TYPE = "CONTENT_TYPE"

      # @since 1.3.0
      # @api private
      MEDIA_TYPE_MATCHER = /\s*[;,]\s*/

      # @since 1.3.0
      # @api private
      RACK_INPUT = "rack.input"

      # @since 1.3.0
      # @api private
      ROUTER_PARAMS = "router.params"

      # @api private
      FALLBACK_KEY = "_"

      extend ClassInterface

      def initialize(app, parsers)
        @app = app
        @parsers = parsers
      end

      def call(env)
        body = env[RACK_INPUT].read
        return @app.call(env) if body.empty?

        env[RACK_INPUT].rewind # somebody might try to read this stream

        if (parser = @parsers[media_type(env)])
          env[Router::ROUTER_PARSED_BODY] = parser.parse(body, env)
          env[ROUTER_PARAMS] = _symbolize(env[Router::ROUTER_PARSED_BODY])
        end

        @app.call(env)
      end

      private

      # @api private
      def _symbolize(body)
        if body.is_a?(::Hash)
          Router::Params.deep_symbolize(body)
        else
          {FALLBACK_KEY => body}
        end
      end

      # @api private
      def _parse(env, body)
        @parsers[
          media_type(env)
        ].parse(body)
      end

      # @api private
      def media_type(env)
        ct = content_type(env)
        return unless ct

        ct.split(MEDIA_TYPE_MATCHER, 2).first.downcase
      end

      # @api private
      def content_type(env)
        content_type = env[CONTENT_TYPE]
        content_type.nil? || content_type.empty? ? nil : content_type
      end
    end
  end
end

Version data entries

11 entries across 11 versions & 1 rubygems

Version Path
hanami-router-2.2.0 lib/hanami/middleware/body_parser.rb
hanami-router-2.2.0.rc1 lib/hanami/middleware/body_parser.rb
hanami-router-2.2.0.beta2 lib/hanami/middleware/body_parser.rb
hanami-router-2.2.0.beta1 lib/hanami/middleware/body_parser.rb
hanami-router-2.1.0 lib/hanami/middleware/body_parser.rb
hanami-router-2.1.0.rc3 lib/hanami/middleware/body_parser.rb
hanami-router-2.1.0.rc2 lib/hanami/middleware/body_parser.rb
hanami-router-2.1.0.rc1 lib/hanami/middleware/body_parser.rb
hanami-router-2.1.0.beta1 lib/hanami/middleware/body_parser.rb
hanami-router-2.0.2 lib/hanami/middleware/body_parser.rb
hanami-router-2.0.1 lib/hanami/middleware/body_parser.rb