diff --git a/limiter.go b/limiter.go index 1da6fce..32281a3 100644 --- a/limiter.go +++ b/limiter.go @@ -22,9 +22,10 @@ type Context struct { // Limiter is the limiter instance. type Limiter struct { - Store Store - Rate Rate - Options Options + Store Store + Rate Rate + Options Options + SkipList SkipList } // New returns an instance of Limiter. @@ -37,15 +38,22 @@ func New(store Store, rate Rate, options ...Option) *Limiter { for _, o := range options { o(&opt) } + whiteList := SkipList{ + Keys: opt.SkipList, + } return &Limiter{ - Store: store, - Rate: rate, - Options: opt, + Store: store, + Rate: rate, + Options: opt, + SkipList: whiteList, } } // Get returns the limit for given identifier. func (limiter *Limiter) Get(ctx context.Context, key string) (Context, error) { + if limiter.SkipList.HasKey(key) { + return Context{}, nil + } return limiter.Store.Get(ctx, key, limiter.Rate) } diff --git a/options.go b/options.go index d8a44ea..4741002 100644 --- a/options.go +++ b/options.go @@ -24,6 +24,9 @@ type Options struct { // proxy is not configured properly to forward a trustworthy client IP. // Please read the section "Limiter behind a reverse proxy" in the README for further information. ClientIPHeader string + + // SkipList represents list of keys which will be skipped by limiter + SkipList []string } // WithIPv4Mask will configure the limiter to use given mask for IPv4 address. @@ -59,3 +62,13 @@ func WithClientIPHeader(header string) Option { o.ClientIPHeader = header } } + +// WithSkipList will configure the limiter to use list of provided +// exception keys (which may be IP addresses or custome header values). +// This list will be consulted at every request and if key will be found in +// SkipList the limiter functionality will be skipped for that key. +func WithSkipList(wlist []string) Option { + return func(o *Options) { + o.SkipList = wlist + } +} diff --git a/whitelist.go b/whitelist.go new file mode 100644 index 0000000..722ba24 --- /dev/null +++ b/whitelist.go @@ -0,0 +1,16 @@ +package limiter + +// SkipList represent white list of keys +type SkipList struct { + Keys []string +} + +// HasKey implements basic look-up of given key in SkipList +func (w *SkipList) HasKey(key string) bool { + for _, k := range w.Keys { + if k == key { + return true + } + } + return false +}