Skip to content

Commit

Permalink
Allow calling close on rack.input. (#1956)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Aug 29, 2022
1 parent 6fc4a32 commit ffee3c5
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. For info on
- `rack.hijack?` (partial hijack) and `rack.hijack` (full hijack) are now independently optional.
- `rack.hijack_io` has been removed completely.
- `rack.response_finished` is an optional environment key which contains an array of callable objects that must accept `#call(env, status, headers, error)` and are invoked after the response is finished (either successfully or unsucessfully).
- It is okay to call `#close` on `rack.input` to indicate that you no longer need or care about the input.

### Removed

Expand Down Expand Up @@ -66,6 +67,7 @@ All notable changes to this project will be documented in this file. For info on
- Use lower case cookie attributes when creating cookies, and fold cookie attributes to lower case when reading cookies (specifically impacting `secure` and `httponly` attributes). ([#1849](https://github.com/rack/rack/pull/1849), [@ioquatix])
- The response array must now be mutable (non-frozen) so middleware can modify it without allocating a new Array,therefore reducing object allocations. ([#1887](https://github.com/rack/rack/pull/1887), [#1927](https://github.com/rack/rack/pull/1927), [@amatsuda], [@ioquatix])
- `rack.hijack?` (partial hijack) and `rack.hijack` (full hijack) are now independently optional. `rack.hijack_io` is no longer required/specified. ([#1939](https://github.com/rack/rack/pull/1939), [@ioquatix])
- Allow calling close on `rack.input`. ([#1956](https://github.com/rack/rack/pull/1956), [@ioquatix])

### Fixed

Expand Down
3 changes: 2 additions & 1 deletion SPEC.rdoc
Expand Up @@ -166,7 +166,8 @@ The input stream must respond to +gets+, +each+, and +read+.
If +buffer+ is given, then the read data will be placed
into +buffer+ instead of a newly created String object.
* +each+ must be called without arguments and only yield Strings.
* +close+ must never be called on the input stream.
* +close+ can be called on the input stream to indicate that the
any remaining input is not needed.

=== The Error Stream

Expand Down
5 changes: 3 additions & 2 deletions lib/rack/lint.rb
Expand Up @@ -478,9 +478,10 @@ def each(*args)
}
end

## * +close+ must never be called on the input stream.
## * +close+ can be called on the input stream to indicate that the
## any remaining input is not needed.
def close(*args)
raise LintError, "rack.input#close must not be called"
@input.close(*args)
end
end

Expand Down
17 changes: 10 additions & 7 deletions test/spec_lint.rb
Expand Up @@ -742,14 +742,17 @@ def each
}).call(env("rack.input" => eof_weirdio))
}.must_raise(Rack::Lint::LintError).
message.must_match(/read\(nil\) returned nil on EOF/)
end

lambda {
Rack::Lint.new(lambda { |env|
env["rack.input"].close
[201, { "content-type" => "text/plain", "content-length" => "0" }, []]
}).call(env({}))
}.must_raise(Rack::Lint::LintError).
message.must_match(/close must not be called/)
it "can call close" do
app = lambda do |env|
env["rack.input"].close
[201, {"content-type" => "text/plain", "content-length" => "0"}, []]
end

response = Rack::Lint.new(app).call(env({}))

response.first.must_equal 201
end

it "notice error handling errors" do
Expand Down

0 comments on commit ffee3c5

Please sign in to comment.