# Nexaas::Throttle
[![Build Status](https://travis-ci.org/myfreecomm/nexaas-throttle.svg?branch=master)](https://travis-ci.org/myfreecomm/nexaas-throttle)
[![Test Coverage](https://codeclimate.com/github/myfreecomm/nexaas-throttle/badges/coverage.svg)](https://codeclimate.com/github/myfreecomm/nexaas-throttle/coverage)
[![Code Climate](https://codeclimate.com/github/myfreecomm/nexaas-throttle/badges/gpa.svg)](https://codeclimate.com/github/myfreecomm/nexaas-throttle)
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:
```ruby
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:
```ruby
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:
```ruby
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:
```ruby
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:
```ruby
"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](https://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](http://opensource.org/licenses/MIT).