summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2020-01-30 15:11:20 -0800
committerJeremy Evans <code@jeremyevans.net>2020-01-30 15:16:10 -0800
commite13c7384293c8dca56591d556268413fdc83d2ba (patch)
tree89504a99a96e34c7cf88667190e7451cc77d227b
parent4804192aaba4319f8a019043eeed84982c2515e7 (diff)
downloadrack-e13c7384293c8dca56591d556268413fdc83d2ba.tar.gz
Make Cascade use a new response object if initialized with no apps
The previous behavior was broken if a middleware modified any part of the response. Modify the logic slightly to use an early return instead of just breaking out of the loop, which should be faster in the general case.
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/rack/cascade.rb7
-rw-r--r--test/spec_cascade.rb19
3 files changed, 23 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59a8ba32..cafa58ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -41,6 +41,7 @@ All notable changes to this project will be documented in this file. For info on
### Fixed
+- `Cascade` uses a new response object for each call if initialized with no apps. ([@jeremyevans](https://github.com/jeremyevans))
- `BodyProxy` correctly delegates keyword arguments to the body object on Ruby 2.7+. ([@jeremyevans](https://github.com/jeremyevans))
- `BodyProxy#method` correctly handles methods delegated to the body object. ([@jeremyevans](https://github.com/jeremyevans))
- `Request#host` and `Request#host_with_port` handle IPv6 addresses correctly. ([@AlexWayfer](https://github.com/AlexWayfer))
diff --git a/lib/rack/cascade.rb b/lib/rack/cascade.rb
index 1ed7ffa9..8a3cf66b 100644
--- a/lib/rack/cascade.rb
+++ b/lib/rack/cascade.rb
@@ -6,6 +6,7 @@ module Rack
# status codes).
class Cascade
+ # deprecated, no longer used
NotFound = [404, { CONTENT_TYPE => "text/plain" }, []]
attr_reader :apps
@@ -19,8 +20,6 @@ module Rack
end
def call(env)
- result = NotFound
-
last_body = nil
@apps.each do |app|
@@ -34,10 +33,10 @@ module Rack
result = app.call(env)
last_body = result[2]
- break unless @catch.include?(result[0].to_i)
+ return result unless @catch.include?(result[0].to_i)
end
- result
+ [404, { CONTENT_TYPE => "text/plain" }, []]
end
def add(app)
diff --git a/test/spec_cascade.rb b/test/spec_cascade.rb
index 299aaad2..883b47c5 100644
--- a/test/spec_cascade.rb
+++ b/test/spec_cascade.rb
@@ -42,6 +42,25 @@ describe Rack::Cascade do
Rack::MockRequest.new(cascade([])).get('/').must_be :not_found?
end
+ it "uses new response object if empty" do
+ app = Rack::Cascade.new([])
+ res = app.call('/')
+ s, h, body = res
+ s.must_equal 404
+ h['Content-Type'].must_equal 'text/plain'
+ body.must_be_empty
+
+ res[0] = 200
+ h['Content-Type'] = 'text/html'
+ body << "a"
+
+ res = app.call('/')
+ s, h, body = res
+ s.must_equal 404
+ h['Content-Type'].must_equal 'text/plain'
+ body.must_be_empty
+ end
+
it "append new app" do
cascade = Rack::Cascade.new([], [404, 403])
Rack::MockRequest.new(cascade).get('/').must_be :not_found?