I'm searching rate-limiting engine for my rails 3 application. I've found some but that's not what i need. I 've found rack-throttle gem and curbit gem. It seems that rack-throttle works for each request to rails application but i need to limit requests only to one action. Curbit was last updated two years ago. Can anyone tell me about any other rate-limiting engines that i can use? Note that it should work with caching.
-
what about throttling on the web server (apache?) – Roger Mar 06 '12 at 09:54
-
@Rogier the project will be deployed on heroku – roman Mar 06 '12 at 10:02
2 Answers
Well, finally rack throttle is a good solution.
You can do it the following way. You need to define your custom limiter. It can be based on either of the following limiters
Rack::Throttle::Limiter
Rack::Throttle::Interval
Rack::Throttle::Hourly
Rack::Throttle::Daily
Everything you need to do is derive from one of the above classes to define custom logic. For example:
class CustomLimiter < Rack::Throttle::Interval
def allowed?(request)
#custom logic here
end
end
You should put this file in the RAILS_ROOT/lib
path. Then in the application.rb
file you should specify what class to use as a limiter. For example if you want to apply limiter only to one action you can do it the following way:
#lib/custom_limiter.rb
class CustomLimiter < Rack::Throttle::Interval
def allowed?(request)
path_info = Rails.application.routes.recognize_path request.url rescue {}
if path_info[:controller] == "application" and path_info[:action] == "check_answer"
super
else
true
end
end
end
#config/application.rb
class Application < Rails::Application
...
#Set up rate limiting
config.require "custom_limiter"
config.middleware.use CustomLimiter, :min => 0.2
...
end
You may need to take this into consideration
Hope this will be useful
UPD:
you may want to check out another solution: rack-attack
-
-
-
1Thanks for the step-by-step. Just to know a bit more about the setup. Are you using a what kind of DB to store the counters? – Eduardo Jan 02 '14 at 11:12
-
Also check out the whitelisted? and blacklisted? methods. https://github.com/datagraph/rack-throttle/blob/master/lib/rack/throttle/limiter.rb#L54-L81 – ifightcrime Apr 25 '14 at 23:54
-
Got caught on this as well. Make sure you also pass `request.request_method` as a second argument to recognize_path (ex: `recognize_path(request.url, request.request_method)`) if you want to rate limit anything other than just GET requests. – ifightcrime Apr 26 '14 at 00:56
-
You might also want to check [Rack::Defense](https://github.com/Sinbadsoft/rack-defense) ([gem](http://rubygems.org/gems/rack-defense)). – nakhli Oct 13 '14 at 07:50
rack-throttle
does what you want. Subclass Limiter
and define your own #allowed?
method. Simply return true if the request isn't the action you want the limit and don't count it towards the limit. Take a look at daily.rb
. Redefine #cache_set
so it doesn't save those that don't match the route you want to limit.

- 21,472
- 14
- 74
- 123
-
I've overrided it, and put the file in the lib directory and restarted the server but it doesn't work. `class CustomLimiter < Rack::Throttle::Limiter def allowed?(request) true == true end end` The page is opened but the assets are not loaded and i get `ERROR NoMethodError: undefined method `each' for "403 Forbidden (Rate Limit Exceeded)` So the styles are not applied. In `application.rb` i have `config.middleware.use Rack::Throttle::Interval, :min => 0.2`. What's wrong? – roman Mar 06 '12 at 10:57