Documentation ¶
Overview ¶
Package apitok implements rate limiting api calls based on tokens/ips
Index ¶
- func New(secret []byte) string
- type RateLimitMem
- func (m *RateLimitMem) Clean(staleTimeout time.Duration)
- func (m *RateLimitMem) DecrBy(key string, amount int64) int64
- func (m *RateLimitMem) Get(key string) int64
- func (m *RateLimitMem) IncrByCeil(key string, amount, max int64) (int64, bool)
- func (m *RateLimitMem) LastModified(key string) time.Time
- type RateLimitStore
- type RateLimiter
- type UseResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type RateLimitMem ¶
type RateLimitMem struct {
// contains filtered or unexported fields
}
RateLimitMem is an implementation of RateLimitStore which keeps all data in memory protected by a mutex
func NewRateLimitMem ¶
func NewRateLimitMem() *RateLimitMem
NewRateLimitMem returns a new RateLimitMem, ready to be used as a RateLimitStore
func (*RateLimitMem) Clean ¶
func (m *RateLimitMem) Clean(staleTimeout time.Duration)
Clean is an implementation of Clean for RateLimitStore
func (*RateLimitMem) DecrBy ¶
func (m *RateLimitMem) DecrBy(key string, amount int64) int64
DecrBy is an implementation of DecrBy for RateLimitStore
func (*RateLimitMem) Get ¶
func (m *RateLimitMem) Get(key string) int64
Get is an implementation of Get for RateLimitStore
func (*RateLimitMem) IncrByCeil ¶
func (m *RateLimitMem) IncrByCeil(key string, amount, max int64) (int64, bool)
IncrByCeil is an implementation of IncrByCeil for RateLimitStore
func (*RateLimitMem) LastModified ¶
func (m *RateLimitMem) LastModified(key string) time.Time
LastModified is an implementation of LastModified for RateLimitStore
type RateLimitStore ¶
type RateLimitStore interface { // Increments the given key by the given amount, and returns the value of // the key after the increment. If the key would go over the max value given // it should be instead set to that max (and have that max returned). True // should be returned in this case as well. The key should be assumed to be // 0 if it didn't previously exist IncrByCeil(key string, amount, max int64) (int64, bool) // Decrements the given key by the given amount, and returns the value of // the key after the decrement. The key should be assumed to be 0 if it // didn't previously exist DecrBy(key string, amount int64) int64 // Retrieve the value of the given key. The key should be assumed to be 0 if // it didn't previously exists Get(key string) int64 // The time the key was last modified. Returns the zero time if the key did // not previously exist LastModified(key string) time.Time // Will be called once a minute, and should be used to atomically clean up // any data which hasn't been modified in more than the given duration. If // the backing storage method has a different way of implicitely cleaning up // data (e.g. redis' EXPIRE command) than this may do nothing Clean(time.Duration) }
RateLimitStore is used to store data needed for rate limiting. All methods must be thread-safe with each other
type RateLimiter ¶
type RateLimiter struct { // The maximum time available per api token. Default is 30 seconds Capacity time.Duration // How often time is added to each bucket. Default is 5 seconds Interval time.Duration // How much time is added to each bucket every Interval. Default is 5 // seconds PerInterval time.Duration // Where to actually store data pertaining to the RateLimiter. Default is // a new instance of RateLimitMem (which stores all data in memory) Backend RateLimitStore }
RateLimiter implements a token bucket rate limiting system on a per-api-token basis, except instead of tokens in the bucket we instead use time. When a request is made it's first checked if the bucket is empty, if so the request is rejected. When the request is completed the time it took to complete is removed from the bucket (the bucket may have negative time in it)
At intervals new time is added to the bucket, up to a specified maximum capacity. This system has a few nice qualities:
- Bursts of load are allowed, but not sustained load
- Load is determined by actual time per request, so the system can't be easily gamed by making high cost requests.
- It's pretty cheap and easy to implement
func NewRateLimiter ¶
func NewRateLimiter() *RateLimiter
NewRateLimiter returns a new RateLimiter initialized with all default values. The fields can be changed to the desired values before the RateLimiter starts being used
func (*RateLimiter) CanUse ¶
func (r *RateLimiter) CanUse(token string, secret []byte) UseResult
CanUse attempts to use the given api token (calling sig.Verify on it first). May return any of the UseResults
func (*RateLimiter) CanUseRaw ¶
func (r *RateLimiter) CanUseRaw(identifier string) UseResult
CanUseRaw checks if you can "use" the given identifier, which could be anything, checking that it has a non-zero amount of time in its bucket first. Will either return Success or RateLimited