Fix `respond_to?(:each)` with `Rack::Lint` with streaming bodies. (#1981)

* Fix handling of `to_path` and add spec.

* Also forward `call`.
This commit is contained in:
Samuel Williams 2022-11-12 12:37:26 +13:00 committed by GitHub
parent da473d810e
commit 00aa541d4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 2 deletions

View File

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. For info on
### Fixed
- `MethodOverride` does not look for an override if a request does not include form/parseable data.
- `Rack::Lint::Wrapper` correctly handles `respond_to?` with `to_ary`, `each`, `call` and `to_path`, forwarding to the body. ([#1981](https://github.com/rack/rack/pull/1981), [@ioquatix])
## [3.0.0] - 2022-09-06

View File

@ -817,8 +817,14 @@ module Rack
verify_to_path
end
BODY_METHODS = {to_ary: true, each: true, call: true, to_path: true}
def to_path
@body.to_path
end
def respond_to?(name, *)
if name == :to_ary
if BODY_METHODS.key?(name)
@body.respond_to?(name)
else
super

View File

@ -33,7 +33,6 @@ describe Rack::Lint do
lambda { Rack::Lint.new(nil).call({}.freeze) }.must_raise(Rack::Lint::LintError).
message.must_match(/env should not be frozen, but is/)
lambda {
e = env
e.delete("REQUEST_METHOD")
@ -473,6 +472,17 @@ describe Rack::Lint do
message.must_match(/content-length header was 1, but should be 0/)
end
it "responds to to_path" do
body = Object.new
def body.each; end
def body.to_path; __FILE__ end
app = lambda { |env| [200, {}, body] }
status, headers, body = Rack::Lint.new(app).call(env({}))
body.must_respond_to(:to_path)
body.to_path.must_equal __FILE__
end
it "notice body errors" do
lambda {
body = Rack::Lint.new(lambda { |env|