-
Notifications
You must be signed in to change notification settings - Fork 340
Description
Upon upgrading to 6.2.1 (from 6.1.0), we end up with Rack::Attack twice in our middleware stack.
Actual behavior:
$ rails middleware
...
use Rack::Head
use Rack::ConditionalGet
use Authenticator::PartOne
use Rack::Attack # <--- our intended Rack::Attack instance
use Authenticator::PartTwo
use Rack::Attack # <--- the duplicate now added in 6.2 that we don't want
run OurApp::Application.routes
Expected behavior:
$ rails middleware
...
use Authenticator::PartOne
use Rack::Attack # <--- our intended Rack::Attack instance
use Authenticator::PartTwo
run OurApp::Application.routes
As you can see, our specific case involves a two-phase authentication middleware stack that is specifically designed to surround Rack::Attack, so we cannot move Rack::Attack to the end of the stack, where it installs itself by default.
I see that 6.2.1 was intended to turn the second instance into a no-op, but we'd much prefer avoiding the double load to begin with.
Given the need to configure Rack::Attack anyway, one could argue against auto-loading the middleware. However, I'd like to instead propose a couple of ways to allow disabling the auto-load for advanced configurations like ours, while preserving it as the new default behavior.
-
Add a config option
Rack::Attack.auto_load = true
. Defaults to true. When false, the initializer would skip the auto-load. -
Rework the gem's default require by moving most of lib/rack/attack.rb into a new file. Replace the original file with nothing but:
require 'rack/attack/<newfile>'
require 'rack/attack/railtie' if defined?(::Rails)
This would allow advanced configurations to set the Gemfile as
gem 'rack-attack', require: 'rack/attack/<newfile>'
which would implicitly disable the auto-load railtie.
Either way preserves your new default while adding a path for more specific configuration for those of us with apps with advanced middleware configurations.
Are you open to either of the above solutions? If at least one is acceptable, I'm happy to prepare a PR accordingly if that'd be helpful.
FWIW, either of the above would also allow the removal of the already-called condition (return ... if ... env["rack.attack.called"]
) added in #457, which I think may break/prevent PR #442.