aars / rack-bodyparser

Rack Middleware for parsing request body.
MIT License
6 stars 0 forks source link

Does not abide by Rack SPEC #4

Open qortex opened 4 years ago

qortex commented 4 years ago

Rack::Lint enforces SPEC:

      ## The CGI keys (named without a period) must have String values.
      ## If the string values for CGI keys contain non-ASCII characters,
      ## they should use ASCII-8BIT encoding.
      env.each { |key, value|
        next  if key.include? "."   # Skip extensions
        assert("env variable #{key} has non-string value #{value.inspect}") {
          value.kind_of? String
        }
        next if value.encoding == Encoding::ASCII_8BIT
        assert("env variable #{key} has value containing non-ASCII characters and has non-ASCII-8BIT encoding #{value.inspect} encoding: #{value.encoding}") {
          value.b !~ /[\x80-\xff]/n
        }
      }

Thus, enabling Rack::Lint middleware generates an exception:

Rack::Lint::LintError: env variable parsed_body has non-string value

The CGI keys (named without a period) must have String values. suggests a fix would be to rename it to body_parser.document or something like that, to abide by the convention. Although of course it would be a breaking change.

qortex commented 4 years ago

Source file: https://github.com/rack/rack/blob/master/lib/rack/lint.rb

qortex commented 4 years ago

Quick workaround, simply rename the key by hand:

module BodyParser
  # To abide by Rack::Lint, where without a dot in the key name it should be string (here, it can be
  # a Hash instead, so Rack::Lint throws)
  class KeyRenamer
    FROM_KEY = 'parsed_body'
    TO_KEY = 'parsed_body.document'

    def initialize(app, _opts = {})
      @app = app
    end

    def call(env)
      new_env = env
      if new_env.key?(FROM_KEY)
        new_env[TO_KEY] = new_env[FROM_KEY]
        new_env.delete(FROM_KEY)
      end

      @app.call(new_env)
    end
  end
end
qortex commented 4 years ago

Btw, formal spec is here, which states:

The server or the application can store their own data in the environment, too. The keys must contain at least one dot, and should be prefixed uniquely.

aars commented 4 years ago

Thanks for raising this issue. I'll try to update asap. I'll bump the version to express the breaking change.