Get ordered list of middleware in a generic rack application?
$ rake middlewareuse ActionDispatch::Staticuse Rack::Lockuse #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd148f9468>use Rack::Runtimeuse Rack::MethodOverrideuse ActionDispatch::RequestIduse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::DebugExceptionsuse ActionDispatch::RemoteIpuse ActionDispatch::Reloaderuse ActionDispatch::Callbacksuse ActiveRecord::Migration::CheckPendinguse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::Headuse Rack::ConditionalGetuse Rack::ETagrun 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 }endapp = Rack::Builder.parse_file('config.ru').first; nil # trailing nil to avoid paging in an interactive consolep middleware_classes(app)
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 }endsinatra_app = Rack::Builder.parse_file('config.ru').firstsinatra_rack_builder = sinatra_app.build(sinatra_app)sinatra_extended_app = sinatra_rack_builder.to_apprack_app = sinatra_extended_app.apppp 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.