Closed radar closed 3 months ago
This is expected behavior if you are using an incorrect line terminator (\n
is incorrect, you must use \r\n
, see RFC 1341 section 7.2.1). In rack 3, you get Rack::Multipart::EmptyContentError
(a subclass of EOFError
), to allow for more targeted rescuing.
Not related, and not an issue in your particular example, but when constructing the valid request, you should use content.bytesize
instead of content.length
, since the Content-Length
should be in bytes and not characters.
I don't know of a tool to validate HTTP requests off the top of my head, but I'm guessing one exists.
I'll leave this open for a bit to allow for comments by another maintainer, in case I missed something.
I agree with @jeremyevans and I don't think we should do anything here. If we did decide to change the behaviour to be more lenient, we might end up causing more long term confusion. Perhaps as an alternative, we could introduce Rack::Multipart::Lint
which is specifically aware of these issues and reports them.
Regarding specific answers:
For further investigation/scope, I looked at other similar issues:
If you think introducing Rack::Mutipart::Lint
is worth the effort, please feel free to open a PR.
I've been trying to track down recently why a particular request would cause a "400 Bad Request" HTTP status on Rack 2.2.7. The request comes from a 3rd party's code that I don't have access to, but I do have access to a curl script that they provided me with that generates a request in the same shape that their code does. Both result in the same 400 Bad Request response, or from Rack itself an
EOFError
.The curl request is:
And a simple Rack app that reproduces this issue:
My best guess here from playing around with the raw HTTP request itself is that the line endings on the multipart data are wrong, leading to a too-short
Content-Type
header.I've got a Ruby script that manually constructs a valid request:
Then I can pipe this through to Rack with:
cat bad-request | nc localhost 9292
However, if I comment out:
And then run the Ruby script again, and pipe it to Rack, I will now start seeing these
EOFError
lines once again.So a couple of questions: