Skip to content

myfreecomm/nexaas-throttle

Repository files navigation

Nexaas::Throttle

Build Status Test Coverage Code Climate

A configurable Rails engine that provides a common way of reducing API abuse, throttling consumers' requests and blocking undesired pentesters and robots.

Installation

Add this line to your application's Gemfile:

gem 'nexaas-throttle'

And then execute:

$ bundle

Or install it yourself as:

$ gem install nexaas-throttle

Usage

In a Rails initializer file such as config/initializers/nexaas_throttle.rb, put something like this:

require "nexaas/throttle"

Nexaas::Throttle.configure do |config|
  config.throttle = true
  config.track = true
  config.period = 1.minute
  config.limit = 2
  config.request_identifier = MyRequestIdentifier
  config.redis_options = {
    host: "localhost",
    port: 6379,
    db: 0,
    namespace: "nexaas:throttle"
  }
  config.ignored_user_agents = [/[Gg]oogle/, /Amazon/]
  config.assets_extensions = %w[bmp tiff css js jpg jpeg png gif woff ttf svg]
end

Configuration

Option Description Default
throttle Whether or not requests are throttled. true
track Whether or not requests are tracked. true
period The size of the throttle window. 1 minute
limit How many requests a consumer can do during a window until he starts being throttled. 60 requests
request_identifier The class that will handle request identification. See Request Identification for more details. nil
redis_options Redis hash configuration where requests counters are persisted.
{
  host: "localhost",
  port: 6379,
  db: 0,
  namespace: "nexaas:throttle"
}
      
ignored_user_agents An array of User Agents that should be ignored by the throttler. Values are regexes that will be matched against the request User-Agent nil
assets_extensions An array of file extensions considered to be asset-related. Values are strings that will be matched against the request path. Paths that match will be not be throttled %w[css js jpg jpeg png gif woff ttf svg]

Request Identification

Nexaas::Throttle doesn't know how to identify a consumer. Some applications might rely on request IP, others on an API TOKEN. You must provide a way of getting an unique token that identify a request consumer.

If there is no token, the request will go through and won't be accounted for.

Nexaas::Throttle do this by providing a configuration request_identifier, a class where your application would keep the logic that identifies a consumer. This class must have the following interface:

class MyRequestIdentifier
  def initialize(request)
    @request = request
  end

  def token
    @request.ip
    # or @request.env["HTTP_AUTHORIZATION"]
    # or User.find_by(token: @request.params[:token])
    # or Cache.read(@request.params[:token])
  end
end

Tracking requests

In order to track your requests, you must subscribe to a event triggered by Rack::Attack gem as below:

ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, request|
  if request.env["rack.attack.matched"] == "nexaas/track" && request.env["rack.attack.match_type"] == :track
    # Put your tracking logic here
    # You can use request.env["nexaas.token"] to obtain the token provided by your request_identifier
  end
end

If you want, you can access the request token by inspecting request.env["nexaas.token"]. This is the token your request_identifier provided after evaluating the request.

Response headers

Rate limit headers are available for all request responses and provide information for API users. They are the following:

"X-RateLimit-Limit"     # Total of requests allowed until next reset.
"X-RateLimit-Remaining" # Amount of requests the user can still send before being throttled.
"X-RateLimit-Reset"     # Epoch time for the reset of the request count.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/myfreecomm/nexaas-throttle.

License

The gem is available as open source under the terms of the MIT License.

About

Common code for HTTP access limiting for Nexaas Ruby apps

Resources

License

Stars

Watchers

Forks

Packages

No packages published