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

Fix error with body.rewind with rack 3.0 #1107

Merged
merged 1 commit into from Oct 19, 2022
Merged

Fix error with body.rewind with rack 3.0 #1107

merged 1 commit into from Oct 19, 2022

Conversation

aglushkov
Copy link
Contributor

In rack 3.0 there are no method #rewind in Rack::Lint::InputWrapper that existed in rack 2.2

Type of change

  • Bug fix (non-breaking change that fixes an issue)

Related issues

@brianr
Copy link
Member

brianr commented Oct 7, 2022

Thanks @aglushkov , we're taking a look at this.

@waltjones
Copy link
Contributor

@aglushkov Thanks for bringing up this issue, and thank you for the PR.

I looked up the rack issue (rack/rack#1148) and PR (rack/rack#1804) for more insight.

My concern about this PR is that the input is still IO-like, and reading from it will still update the IO cursor. The difference is that since it is non-rewindable, it can only be read once, so rollbar-gem probably shouldn't be reading it.

Am I missing something that would make this safe as is?

@aglushkov
Copy link
Contributor Author

@waltjones Your concerns are correct.

  • If input was already read, you can not read it again (so you can receive issues, that input data was not tracked by Rollbar)
  • If input was not read, you can read it, but no one can do it after.

There are Rack::RewindableInput class in Rack-2
and additional Rewindable::Middleware in Rack-3 that can be used to get around this issues. But using them can be also an issue, as they will copy input to Tempfile, that can be no desirable behavior for application.

I would suggest using not-public body.instance_variable_get(:@input) interface for Rack 3.0 to achieve previous behavior for most applications without Rack::RewindableInput.

def rewind_body(rack_req)
     body = rack_req.body
     if body.respond_to?(:rewind)
       body.rewind
     else
       # workaround for Rack 3.0
       # for my application (Rack, Roda, Puma) `body_input` is StringIO, Puma::NullIO, Tempfile, everything is rewindable
       body_input = body.instance_variable_get(:@input) 
       body_input.rewind if body_input.respond_to?(:rewind) # additional check if its not rewindable
   end
end

Such should be used before and after reading input.

@waltjones
Copy link
Contributor

@aglushkov Nice workaround!

I have two suggestions.

  • We need to check for nil body_input, since @input could be removed/renamed in the future.
  • We need to skip rack_req.body.read if the input is not rewindable. For example, something like:
return {} unless rewindable?(rack_req)

@aglushkov
Copy link
Contributor Author

It turns out this @input is only present when Rack::Lint middleware is used. It is enabled by default by Rackup, but can be disabled with --env none option. In most production apps, where Rollbar is used it should be disabled, so having
req.body.rewind if req.body.respond_to?(:rewind) should be enough to satisfy new Rack3 specification

@waltjones
Copy link
Contributor

@aglushkov That sounds fine. We still need to skip rack_req.body.read if the input is not rewindable.

#1106

In rack 3.0 there are no method `#rewind` in Rack::Lint::InputWrapper
that existed in rack 2.2
@aglushkov
Copy link
Contributor Author

@waltjones Sorry for delay, I've update PR, add test

@waltjones waltjones self-requested a review October 19, 2022 14:24
Copy link
Contributor

@waltjones waltjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aglushkov Nice work. Thank you for the test coverage, and thank you again for the PR.

@waltjones waltjones merged commit 0d8e838 into rollbar:master Oct 19, 2022
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

Successfully merging this pull request may close these issues.

Error when sending error with Rack 3.0 app
3 participants