diff options
author | Jeremy Evans <code@jeremyevans.net> | 2020-01-30 15:11:20 -0800 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2020-01-30 15:16:10 -0800 |
commit | e13c7384293c8dca56591d556268413fdc83d2ba (patch) | |
tree | 89504a99a96e34c7cf88667190e7451cc77d227b | |
parent | 4804192aaba4319f8a019043eeed84982c2515e7 (diff) | |
download | rack-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.md | 1 | ||||
-rw-r--r-- | lib/rack/cascade.rb | 7 | ||||
-rw-r--r-- | test/spec_cascade.rb | 19 |
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? |