Rack::Cascade tries an request on several apps, and returns the first response that is not 404 (or in a list of configurable status codes).
[~/local/src/ruby/sinatra/rack/rack-cascade]$ cat cascade2.ru
statuses = [200,404]
apps = [
lambda {|env|
status = statuses.sample
[status, {}, ["I'm the first app. Status = #{status}\n"]]
},
lambda {|env|
status = statuses.sample
[status, {}, ["I'm the second app. Status = #{status}\n"]]
},
lambda {|env|
status = statuses.sample
[status, {}, ["I'm the last app. Status = #{status}\n"]]
}
]
use Rack::ContentLength
use Rack::ContentType
run Rack::Cascade.new(apps)
[~/local/src/ruby/sinatra/rack/rack-cascade]$ rake client curl -v 'http://localhost:9292' * About to connect() to localhost port 9292 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 9292 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5 > Host: localhost:9292 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 33 < Connection: keep-alive < Server: thin 1.5.1 codename Straight Razor < I'm the second app. Status = 200 * Connection #0 to host localhost left intact * Closing connection #0
[~/local/src/ruby/sinatra/rack/rack-cascade]$ rake client curl -v 'http://localhost:9292' * About to connect() to localhost port 9292 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 9292 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5 > Host: localhost:9292 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 31 < Connection: keep-alive < Server: thin 1.5.1 codename Straight Razor < I'm the last app. Status = 200 * Connection #0 to host localhost left intact * Closing connection #0
[~/local/src/ruby/sinatra/rack/rack-cascade]$ rake client curl -v 'http://localhost:9292' * About to connect() to localhost port 9292 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 9292 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5 > Host: localhost:9292 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 32 < Connection: keep-alive < Server: thin 1.5.1 codename Straight Razor < I'm the first app. Status = 200 * Connection #0 to host localhost left intact * Closing connection #0]
# File lib/rack/cascade.rb, line 11
11: def initialize(apps, catch=404)
12: @apps = []; @has_app = {}
13: apps.each { |app| add app }
14:
15: @catch = {}
16: [*catch].each { |status| @catch[status] = true }
17: end
# File lib/rack/cascade.rb, line 19
19: def call(env)
20: result = NotFound
21:
22: @apps.each do |app|
23: result = app.call(env)
24: break unless @catch.include?(result[0].to_i)
25: end
26:
27: result
28: end