Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not abide by Rack SPEC #4

Open
qortex opened this issue Apr 10, 2020 · 4 comments
Open

Does not abide by Rack SPEC #4

qortex opened this issue Apr 10, 2020 · 4 comments

Comments

@qortex
Copy link

qortex commented Apr 10, 2020

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
Copy link
Author

qortex commented Apr 10, 2020

@qortex
Copy link
Author

qortex commented Apr 10, 2020

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
Copy link
Author

qortex commented Apr 11, 2020

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.

@qortex qortex changed the title Does not abide by Rack::Lint Does not abide by Rack SPEC Apr 11, 2020
@aars
Copy link
Owner

aars commented Apr 20, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants