Restored throttling after removing side effects
Andrew Kane
committed Aug 19, 2016
commit cff7cc19cbbfde834ce67f0affdf1c98777bd32d
Showing 6
changed files with
44 additions
and 16 deletions
CHANGELOG.md
+4
-0
| @@ | @@ -1,3 +1,7 @@ |
| + | ## 1.5.1 [unreleased] |
| + | |
| + | - Restored throttling after removing side effects |
| + | |
| ## 1.5.0 | |
| - Removed throttling due to unintended side effects with its implementation | |
README.md
+0
-16
| @@ | @@ -530,18 +530,6 @@ Send a `POST` request as `Content-Type: application/json` to `/ahoy/events` with |
| Use an array to pass multiple events at once. | |
| - | ## Throttling |
| - | |
| - | To throttle requests to Ahoy endpoints, check out [Rack::Attack](https://github.com/kickstarter/ack-attack). Here’s a sample config: |
| - | |
| - | ```ruby |
| - | Rack::Attack.throttle("ahoy/ip", limit: 20, period: 1.minute) do |req| |
| - | if req.path.start_with?("/ahoy/") |
| - | req.ip |
| - | end |
| - | end |
| - | ``` |
| - | |
| ## Reference | |
| By default, Ahoy create endpoints at `/ahoy/visits` and `/ahoy/events`. To disable, use: | |
| @@ | @@ -552,10 +540,6 @@ Ahoy.mount = false |
| ## Upgrading | |
| - | ### 1.5.0 |
| - | |
| - | There’s nothing to do, but it’s worth noting that simple throttling, which was added in `1.3.0`, was removed due to unintended side effects with its implementation. See the [Throttling](#throttling) section for how to properly add it by hand if needed. |
| - | |
| ### 1.4.0 | |
| There’s nothing to do, but it’s worth noting the default store was changed from `ActiveRecordStore` to `ActiveRecordTokenStore` for new installations. | |
ahoy_matey.gemspec
+1
-0
| @@ | @@ -27,6 +27,7 @@ Gem::Specification.new do |spec| |
| spec.add_dependency "request_store" | |
| spec.add_dependency "uuidtools" | |
| spec.add_dependency "safely_block", ">= 0.1.1" | |
| + | spec.add_dependency "rack-attack", "< 6" |
| spec.add_development_dependency "bundler", "~> 1.5" | |
| spec.add_development_dependency "rake" | |
ahoy.rb b/lib/ahoy.rb
+9
-0
| @@ | @@ -72,6 +72,15 @@ module Ahoy |
| mattr_accessor :mount | |
| self.mount = true | |
| + | mattr_accessor :throttle |
| + | self.throttle = true |
| + | |
| + | mattr_accessor :throttle_limit |
| + | self.throttle_limit = 20 |
| + | |
| + | mattr_accessor :throttle_period |
| + | self.throttle_period = 1.minute |
| + | |
| mattr_accessor :job_queue | |
| self.job_queue = :ahoy | |
ahoy/engine.rb b/lib/ahoy/engine.rb
+5
-0
| @@ | @@ -1,6 +1,11 @@ |
| module Ahoy | |
| class Engine < ::Rails::Engine | |
| initializer "ahoy.middleware", after: "sprockets.environment" do |app| | |
| + | if Ahoy.throttle |
| + | require "ahoy/throttle" |
| + | app.middleware.use Ahoy::Throttle |
| + | end |
| + | |
| next unless Ahoy.quiet | |
| # Parse PATH_INFO by assets prefix | |
ahoy/throttle.rb b/lib/ahoy/throttle.rb
+25
-0
| @@ | @@ -0,0 +1,25 @@ |
| + | require "rack/attack" |
| + | |
| + | module Ahoy |
| + | class Throttle < Rack::Attack |
| + | throttle("ahoy/ip", limit: Ahoy.throttle_limit, period: Ahoy.throttle_period) do |req| |
| + | if req.path.start_with?("/ahoy/") |
| + | req.ip |
| + | end |
| + | end |
| + | |
| + | def_delegators self, :whitelisted?, :blacklisted?, :throttled?, :tracked?, :blocklisted?, :safelisted? |
| + | |
| + | def self.throttled_response |
| + | Rack::Attack.throttled_response |
| + | end |
| + | |
| + | def self.blacklisted_response |
| + | Rack::Attack.blacklisted_response |
| + | end |
| + | |
| + | def self.blocklisted_response |
| + | Rack::Attack.blocklisted_response |
| + | end |
| + | end |
| + | end |