Get ordered list of middleware in a generic rack application?
If you're using a Sinatra app that extends Sinatra::Base
, I had to use a slightly modified version of Michael Hale's answer:
require 'rack'
def middleware_classes(app)
r = [app]
while ((next_app = r.last.instance_variable_get(:@app)) != nil)
r << next_app
end
r.map{|e| e.instance_variable_defined?(:@app) ? e.class : e }
end
sinatra_app = Rack::Builder.parse_file('config.ru').first
sinatra_rack_builder = sinatra_app.build(sinatra_app)
sinatra_extended_app = sinatra_rack_builder.to_app
rack_app = sinatra_extended_app.app
pp middleware_classes(rack_app)
After putting this into a file such as dump_middleware.rb
I was able to see the middleware as expected:
$ bundle exec ruby ./dump_middleware.rb
[Rack::Head,
Rack::NullLogger,
Rack::Session::Cookie,
Rack::Protection::FrameOptions,
Rack::Protection::HttpOrigin,
Rack::Protection::IPSpoofing,
Rack::Protection::JsonCsrf,
Rack::Protection::PathTraversal,
Rack::Protection::RemoteToken,
Rack::Protection::SessionHijacking,
Rack::Protection::XSSHeader,
Warden::Manager,
SinatraApp]
There might be a cleaner way to do this.
$ rake middleware
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd148f9468>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run RackTest::Application.routes
http://pothibo.com/2013/11/ruby-on-rails-inside-actiondispatch-and-rack/
This will return a list of all the middleware for a rack application:
def middleware_classes(app)
app.instance_variable_get(:@use).map{|middleware| middleware.call.class.name }
end
app = Rack::Builder.parse_file('config.ru').first; nil # trailing nil to avoid paging in an interactive console
p middleware_classes(app)