Skip to content

Commit

Permalink
Add 1 second buffer to expiry to correct throttles
Browse files Browse the repository at this point in the history
Fixes #69.

There was a race condition when `Time.now.to_i` changes between when
`epoch_time` is computed in line 18, and the cache request is made (and
the `key` is expired).

I.e., a throttle check starts at t0, but doesn’t reach the cache until
t1, the cache will have expired the throttle count. The request will
likely be allowed, even if the request exceeded the limit.

This has the effect of keeping keys in cache about 1 second longer than
strictly necessary. But the extra cache space seems like a good
trade-off for correct throttling.
  • Loading branch information
ktheory committed Sep 2, 2014
1 parent ba52e2c commit 074e8e5
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/rack/attack/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def store=(store)

def count(unprefixed_key, period)
epoch_time = Time.now.to_i
expires_in = period - (epoch_time % period)
# Add 1 to expires_in to avoid timing error: http://git.io/i1PHXA
expires_in = period - (epoch_time % period) + 1
key = "#{prefix}:#{(epoch_time/period).to_i}:#{unprefixed_key}"
do_count(key, expires_in)
end
Expand Down

0 comments on commit 074e8e5

Please sign in to comment.