undefined method `rewind' for #<Rack::Lint::Wrapper::InputWrapper w/Rack >= 3.0
andrius opened this issue · 5 comments
I use a simple ruby (not rails) API with grape, grape-entiry and grape-swagger gems, along with the mongoid. For POST or PUT endpoints it does throw the following error:
NoMethodError: undefined method `rewind' for #<Rack::Lint::Wrapper::InputWrapper:0x0000ffffa610b728 @input=#<StringIO:0x0000ffffa610bf48>> (NoMethodError)
input.rewind
^^^^^^^
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/formatter.rb:87:in `read_body_input'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/formatter.rb:20:in `before'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/base.rb:34:in `call!'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/base.rb:29:in `call'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/error.rb:39:in `block in call!'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/error.rb:38:in `catch'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/error.rb:38:in `call!'
/usr/local/bundle/gems/grape-2.0.0/lib/grape/middleware/base.rb:29:in `call'
/usr/local/bundle/gems/rack-3.0.8/lib/rack/head.rb:15:in `call'
Based on online search I've found that similar issues were long time ago and were fixed, but here it is. Any ideas how to fix it? Happy to share more details or code snippets!
This is caused by lack of rewind
on the input in Rack. Typically that would extend https://github.com/rack/rack/blob/main/lib/rack/rewindable_input.rb, but it looks like Rack::Lint::Wrapper::InputWrapper
doesn't have that. What is the actual setup you have that makes the content that type? Try building a minimal repro?
Thank you. I've included minimal example in this gist: https://gist.github.com/andrius/50e2965a9b0936a7c76f9d7f77bdc2a7
To run:
docker compose build && docker compose run --rm --interactive --service-ports api
To test:
curl -X POST \
'http://localhost:3000/v1/users' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "foo", "lastname": "bar", "email": "foo@bar.foo", "telephone": "+1234567890", "role": "user"}'
Found the issue, rack/rack#1972. Adding use Rack::RewindableInput::Middleware
fixed the issue for me, so would downgrading to Rack 2.x.
require_relative 'api'
use Rack::RewindableInput::Middleware
run API::Root
We should do something about this in Grape. Would you like to help @andrius? We have https://github.com/ruby-grape/grape/tree/master/spec/integration/rack/v3 and https://github.com/ruby-grape/grape/blob/master/gemfiles/rack_3_0.gemfile, but we're not catching this error. The first thing to figure out is how to reproduce it in CI, then we can see whether we should just recommend including this middleware manually, or more likely have to write some code to include it when Rack version is >= 3.0.
Your suggestion with use Rack::RewindableInput::Middleware
helped and API start working!
Would you like to help @andrius?
I will try but it will take time. Just check'ed the GitHub workflows
Should be fixed in the latest release. Could you test it out ?