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