Skip to content

Handle EOFError raised by Rack#2161

Merged
dblock merged 5 commits into
ruby-grape:masterfrom
bschmeck:handle-eof-from-rack
Feb 10, 2021
Merged

Handle EOFError raised by Rack#2161
dblock merged 5 commits into
ruby-grape:masterfrom
bschmeck:handle-eof-from-rack

Conversation

@bschmeck

@bschmeck bschmeck commented Feb 9, 2021

Copy link
Copy Markdown
Contributor

In v2.2.0, Rack started raising an EOFError when given an empty body with a multipart upload: rack/rack#1572. Previously, Rack swallowed this error and execution continued normally. This PR translates that error to an InvalidMessageBody exception, letting Grape return a 400 class error, instead of a 500 class error.

Note that the error raised by Rack will change to Rack::Multipart::EmptyContentError in v3 - rack/rack#1688

@bschmeck bschmeck force-pushed the handle-eof-from-rack branch 2 times, most recently from 2676741 to a723b9f Compare February 9, 2021 21:53
In v2.2.0, Rack started raising an EOFError when given an empty body with a
multipart upload - rack/rack#1572  Previously, Rack had
swallowed this error.
Comment thread lib/grape/request.rb Outdated
def params
@params ||= build_params
rescue EOFError
raise Grape::Exceptions::InvalidMessageBody, 'multipart/form-data'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am concerned that this is hardcoding multipart/form-data, input doesn't have to be this way, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't know when Rack would raise this error other than when given a multipart/form-data, but I'm not a Rack expert. I've pushed a commit to use the object's content_type method instead.

This error class seemed the most appropriated, but it requires a content type. I'm happy to create a different error class if that would be preferable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm ok with reusing this error, it makes sense to me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On a second thought, should we create a EmptyMessageBody error?

We most likely are here due to a multipart/form-data Content-Type, but there's
no guarantee of that.
Comment thread spec/grape/endpoint_spec.rb Outdated

it 'returns a 400 if given an invalid multipart body' do
# Rack swallowed this error until v2.2.0
major, minor, _patch = Rack.release.split('.').map(&:to_i)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The "correct" way to do this is to use Gem::Version.new(Rack.release) >= ..., see https://code.dblock.org/2020/07/16/comparing-version-numbers-in-ruby.html if it's helpful.

Let's also externalize the if as a spec condition so we see it properly skipped.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I figured there had to be a better way.

Comment thread lib/grape/request.rb Outdated
def params
@params ||= build_params
rescue EOFError
raise Grape::Exceptions::InvalidMessageBody, 'multipart/form-data'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On a second thought, should we create a EmptyMessageBody error?

@dblock dblock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's also add a gemfile and run it as part of the matrix explicitly with this version of Rack, ala https://github.com/ruby-grape/grape/blob/master/gemfiles/rack2.gemfile

Also move the conditional to a spec condition, to properly skip the spec on
versions of Rack that don't raise an error.
@bschmeck

Copy link
Copy Markdown
Contributor Author

I've cleaned up how the test is skipped for older versions of Rack, added a custom EmptyMessageBody error and explicitly added Rack 2.2 to the test matrix.

I think that addresses all of your comments, but let me know if I missed something.

@dblock dblock merged commit 6a21f80 into ruby-grape:master Feb 10, 2021
@dblock

dblock commented Feb 10, 2021

Copy link
Copy Markdown
Member

Thanks for hanging in here, great job. Merged.

@dblock

dblock commented Feb 10, 2021

Copy link
Copy Markdown
Member

Related, we had #2130, maybe you care to resolve it one way or another? I do think a note on all Rack-related issues could be useful somewhere.

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.

2 participants