I have a response which is a class. While I can still have my class
implement `#[]`, it does look a bit off. On the other side, having
objects, responding to #call, that are not procs is pretty common.
So I propose to invoke the responses with `#call` to let users override
it with response objects, that respond to `#call` instead of `#[]`.
It has a couple of cons:
1. If we slip a typo in the whole line, we won't easily catch it. Can
you guys spot the problem problem in the following line? Chasing such
issues is quite tricky.
```ruby
retry_after = evn['rack.attack.match_data'][:period] rescue nil
```
2. Throwing and catching an exception is quite slower than a new hash
allocation, so there is a speed benefit too.
We are guaranteed from Rack that env is a `Hash`, so we can even use
`Hash#fetch`.
```ruby
retry_after = env.fetch('rack.attack.match_data', {})[:period]
```
This reads better, but always allocates the default value hash, when the
other version allocates it only when needed. If you prefer `Hash#fetch`,
I'm fine with that, as long as we avoid `rescue nil`.
401 Unauthorized suggests that the requests can be
retried with appropriate credentials. 403 explicitly
states that the request should not be repeated.
See #41
An alternate to fail2ban that allows clients until they hit the
thresholds, then blocks them. Think of it like a throttle where you can
block for more than one period.
based on gist from @ktheory https://gist.github.com/ktheory/5723534
Modified slightly to use fail2ban `filter` terminology to simplify
Rack::Attack initializer configuration (only one block is requred for
this approach instead of 2)