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 respond_to?(:each) with Rack::Lint with streaming bodies. #1981

Merged
merged 4 commits into from Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
8 changes: 7 additions & 1 deletion lib/rack/lint.rb
Expand Up @@ -817,8 +817,14 @@ def each
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
Expand Down
12 changes: 11 additions & 1 deletion test/spec_lint.rb
Expand Up @@ -33,7 +33,6 @@ def env(*args)
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")
Expand Down Expand Up @@ -473,6 +472,17 @@ def obj.each; end
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|
Expand Down