Skip to content
Newer
Older
100644 53 lines (40 sloc) 1.3 KB
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
1 module Rack
376fa1e @chneukirchen Add RDocs
chneukirchen authored
2 # Rack::Cascade tries an request on several apps, and returns the
3 # first response that is not 404 (or in a list of configurable
4 # status codes).
5
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
6 class Cascade
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
7 NotFound = [404, {}, []]
8
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
9 attr_reader :apps
10
11 def initialize(apps, catch=404)
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
12 @apps = []; @has_app = {}
13 apps.each { |app| add app }
14
15 @catch = {}
16 [*catch].each { |status| @catch[status] = true }
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
17 end
18
19 def call(env)
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
20 result = NotFound
21
40dcb5f @raggi Cascade now conforms to the body.close SPEC
raggi authored
22 last_body = nil
23
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
24 @apps.each do |app|
40dcb5f @raggi Cascade now conforms to the body.close SPEC
raggi authored
25 # The SPEC says that the body must be closed after it has been iterated
26 # by the server, or if it is replaced by a middleware action. Cascade
27 # replaces the body each time a cascade happens. It is assumed that nil
28 # does not respond to close, otherwise the previous application body
29 # will be closed. The final application body will not be closed, as it
30 # will be passed to the server as a result.
31 last_body.close if last_body.respond_to? :close
32
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
33 result = app.call(env)
40dcb5f @raggi Cascade now conforms to the body.close SPEC
raggi authored
34 last_body = result[2]
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
35 break unless @catch.include?(result[0].to_i)
36 end
37
38 result
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
39 end
8dace60 @scytrin Addition of #add, #<<, and #include? to Cascade, allowing iterative a…
scytrin authored
40
41 def add app
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
42 @has_app[app] = true
8dace60 @scytrin Addition of #add, #<<, and #include? to Cascade, allowing iterative a…
scytrin authored
43 @apps << app
44 end
45
46 def include? app
0ab6b6c @jeremy Allow empty cascades. Reduce #call object allocation overhead. Speed …
jeremy authored
47 @has_app.include? app
8dace60 @scytrin Addition of #add, #<<, and #include? to Cascade, allowing iterative a…
scytrin authored
48 end
49
50 alias_method :<<, :add
f0f0840 @chneukirchen Add Rack::Cascade, to pass on the first non 404 result
chneukirchen authored
51 end
52 end
Something went wrong with that request. Please try again.