diff options
author | 2025-03-09 17:47:56 +0100 | |
---|---|---|
committer | 2025-03-10 01:59:49 +0100 | |
commit | 3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch) | |
tree | f61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/ulule | |
parent | [chore] update URLs to forked source (diff) | |
download | gotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz |
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/ulule')
17 files changed, 0 insertions, 1107 deletions
diff --git a/vendor/github.com/ulule/limiter/v3/.dockerignore b/vendor/github.com/ulule/limiter/v3/.dockerignore deleted file mode 100644 index 983e52bbe..000000000 --- a/vendor/github.com/ulule/limiter/v3/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -# Circle CI directory -.circleci - -# Example directory -examples diff --git a/vendor/github.com/ulule/limiter/v3/.editorconfig b/vendor/github.com/ulule/limiter/v3/.editorconfig deleted file mode 100644 index c7d5dfb1f..000000000 --- a/vendor/github.com/ulule/limiter/v3/.editorconfig +++ /dev/null @@ -1,25 +0,0 @@ -root = true - -[*] -end_of_line = lf -indent_size = 4 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true -insert_final_newline = true -charset = utf-8 - -[*.{yml,yaml}] -indent_size = 2 - -[*.go] -indent_size = 8 -indent_style = tab - -[*.json] -indent_size = 4 -indent_style = space - -[Makefile] -indent_style = tab -indent_size = 4 diff --git a/vendor/github.com/ulule/limiter/v3/.gitignore b/vendor/github.com/ulule/limiter/v3/.gitignore deleted file mode 100644 index 241fb83f3..000000000 --- a/vendor/github.com/ulule/limiter/v3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/vendor -.idea diff --git a/vendor/github.com/ulule/limiter/v3/.golangci.yml b/vendor/github.com/ulule/limiter/v3/.golangci.yml deleted file mode 100644 index 02556edab..000000000 --- a/vendor/github.com/ulule/limiter/v3/.golangci.yml +++ /dev/null @@ -1,79 +0,0 @@ -run: - concurrency: 4 - deadline: 1m - issues-exit-code: 1 - tests: true - - -output: - format: colored-line-number - print-issued-lines: true - print-linter-name: true - - -linters-settings: - errcheck: - check-type-assertions: false - check-blank: false - govet: - check-shadowing: false - use-installed-packages: false - golint: - min-confidence: 0.8 - gofmt: - simplify: true - gocyclo: - min-complexity: 10 - maligned: - suggest-new: true - dupl: - threshold: 80 - goconst: - min-len: 3 - min-occurrences: 3 - misspell: - locale: US - lll: - line-length: 140 - unused: - check-exported: false - unparam: - algo: cha - check-exported: false - nakedret: - max-func-lines: 30 - -linters: - enable: - - megacheck - - govet - - errcheck - - gas - - structcheck - - varcheck - - ineffassign - - deadcode - - typecheck - - unconvert - - gocyclo - - gofmt - - misspell - - lll - - nakedret - enable-all: false - disable: - - depguard - - prealloc - - dupl - - maligned - disable-all: false - - -issues: - exclude-use-default: false - max-per-linter: 1024 - max-same: 1024 - exclude: - - "G304" - - "G101" - - "G104" diff --git a/vendor/github.com/ulule/limiter/v3/AUTHORS b/vendor/github.com/ulule/limiter/v3/AUTHORS deleted file mode 100644 index c751c70a6..000000000 --- a/vendor/github.com/ulule/limiter/v3/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -Primary contributors: - - Gilles FABIO <gilles@ulule.com> - Florent MESSA <florent@ulule.com> - Thomas LE ROUX <thomas@leroux.io> diff --git a/vendor/github.com/ulule/limiter/v3/LICENSE b/vendor/github.com/ulule/limiter/v3/LICENSE deleted file mode 100644 index cb93018e5..000000000 --- a/vendor/github.com/ulule/limiter/v3/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2018 Ulule - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/ulule/limiter/v3/Makefile b/vendor/github.com/ulule/limiter/v3/Makefile deleted file mode 100644 index 90f076e0a..000000000 --- a/vendor/github.com/ulule/limiter/v3/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -.PHONY: test lint - -test: - @(scripts/test) - -lint: - @(scripts/lint) diff --git a/vendor/github.com/ulule/limiter/v3/README.md b/vendor/github.com/ulule/limiter/v3/README.md deleted file mode 100644 index e0024fca4..000000000 --- a/vendor/github.com/ulule/limiter/v3/README.md +++ /dev/null @@ -1,255 +0,0 @@ -# Limiter - -[![Documentation][godoc-img]][godoc-url] -![License][license-img] -[![Build Status][circle-img]][circle-url] -[![Go Report Card][goreport-img]][goreport-url] - -_Dead simple rate limit middleware for Go._ - -- Simple API -- "Store" approach for backend -- Redis support (but not tied too) -- Middlewares: HTTP, [FastHTTP][6] and [Gin][4] - -## Installation - -Using [Go Modules](https://github.com/golang/go/wiki/Modules) - -```bash -$ go get github.com/ulule/limiter/v3@v3.11.2 -``` - -## Usage - -In five steps: - -- Create a `limiter.Rate` instance _(the number of requests per period)_ -- Create a `limiter.Store` instance _(see [Redis](https://github.com/ulule/limiter/blob/master/drivers/store/redis/store.go) or [In-Memory](https://github.com/ulule/limiter/blob/master/drivers/store/memory/store.go))_ -- Create a `limiter.Limiter` instance that takes store and rate instances as arguments -- Create a middleware instance using the middleware of your choice -- Give the limiter instance to your middleware initializer - -**Example:** - -```go -// Create a rate with the given limit (number of requests) for the given -// period (a time.Duration of your choice). -import "github.com/ulule/limiter/v3" - -rate := limiter.Rate{ - Period: 1 * time.Hour, - Limit: 1000, -} - -// You can also use the simplified format "<limit>-<period>"", with the given -// periods: -// -// * "S": second -// * "M": minute -// * "H": hour -// * "D": day -// -// Examples: -// -// * 5 reqs/second: "5-S" -// * 10 reqs/minute: "10-M" -// * 1000 reqs/hour: "1000-H" -// * 2000 reqs/day: "2000-D" -// -rate, err := limiter.NewRateFromFormatted("1000-H") -if err != nil { - panic(err) -} - -// Then, create a store. Here, we use the bundled Redis store. Any store -// compliant to limiter.Store interface will do the job. The defaults are -// "limiter" as Redis key prefix and a maximum of 3 retries for the key under -// race condition. -import "github.com/ulule/limiter/v3/drivers/store/redis" - -store, err := redis.NewStore(client) -if err != nil { - panic(err) -} - -// Alternatively, you can pass options to the store with the "WithOptions" -// function. For example, for Redis store: -import "github.com/ulule/limiter/v3/drivers/store/redis" - -store, err := redis.NewStoreWithOptions(pool, limiter.StoreOptions{ - Prefix: "your_own_prefix", -}) -if err != nil { - panic(err) -} - -// Or use a in-memory store with a goroutine which clears expired keys. -import "github.com/ulule/limiter/v3/drivers/store/memory" - -store := memory.NewStore() - -// Then, create the limiter instance which takes the store and the rate as arguments. -// Now, you can give this instance to any supported middleware. -instance := limiter.New(store, rate) - -// Alternatively, you can pass options to the limiter instance with several options. -instance := limiter.New(store, rate, limiter.WithClientIPHeader("True-Client-IP"), limiter.WithIPv6Mask(mask)) - -// Finally, give the limiter instance to your middleware initializer. -import "github.com/ulule/limiter/v3/drivers/middleware/stdlib" - -middleware := stdlib.NewMiddleware(instance) -``` - -See middleware examples: - -- [HTTP](https://github.com/ulule/limiter-examples/tree/master/http/main.go) -- [Gin](https://github.com/ulule/limiter-examples/tree/master/gin/main.go) -- [Beego](https://github.com/ulule/limiter-examples/blob/master//beego/main.go) -- [Chi](https://github.com/ulule/limiter-examples/tree/master/chi/main.go) -- [Echo](https://github.com/ulule/limiter-examples/tree/master/echo/main.go) -- [Fasthttp](https://github.com/ulule/limiter-examples/tree/master/fasthttp/main.go) - -## How it works - -The ip address of the request is used as a key in the store. - -If the key does not exist in the store we set a default -value with an expiration period. - -You will find two stores: - -- Redis: rely on [TTL](http://redis.io/commands/ttl) and incrementing the rate limit on each request. -- In-Memory: rely on a fork of [go-cache](https://github.com/patrickmn/go-cache) with a goroutine to clear expired keys using a default interval. - -When the limit is reached, a `429` HTTP status code is sent. - -## Limiter behind a reverse proxy - -### Introduction - -If your limiter is behind a reverse proxy, it could be difficult to obtain the "real" client IP. - -Some reverse proxies, like AWS ALB, lets all header values through that it doesn't set itself. -Like for example, `True-Client-IP` and `X-Real-IP`. -Similarly, `X-Forwarded-For` is a list of comma-separated IPs that gets appended to by each traversed proxy. -The idea is that the first IP _(added by the first proxy)_ is the true client IP. Each subsequent IP is another proxy along the path. - -An attacker can spoof either of those headers, which could be reported as a client IP. - -By default, limiter doesn't trust any of those headers: you have to explicitly enable them in order to use them. -If you enable them, **you must always be aware** that any header added by any _(reverse)_ proxy not controlled -by you **are completely unreliable.** - -### X-Forwarded-For - -For example, if you make this request to your load balancer: -```bash -curl -X POST https://example.com/login -H "X-Forwarded-For: 1.2.3.4, 11.22.33.44" -``` - -And your server behind the load balancer obtain this: -``` -X-Forwarded-For: 1.2.3.4, 11.22.33.44, <actual client IP> -``` - -That's mean you can't use `X-Forwarded-For` header, because it's **unreliable** and **untrustworthy**. -So keep `TrustForwardHeader` disabled in your limiter option. - -However, if you have configured your reverse proxy to always remove/overwrite `X-Forwarded-For` and/or `X-Real-IP` headers -so that if you execute this _(same)_ request: -```bash -curl -X POST https://example.com/login -H "X-Forwarded-For: 1.2.3.4, 11.22.33.44" -``` - -And your server behind the load balancer obtain this: -``` -X-Forwarded-For: <actual client IP> -``` - -Then, you can enable `TrustForwardHeader` in your limiter option. - -### Custom header - -Many CDN and Cloud providers add a custom header to define the client IP. Like for example, this non exhaustive list: - -* `Fastly-Client-IP` from Fastly -* `CF-Connecting-IP` from Cloudflare -* `X-Azure-ClientIP` from Azure - -You can use these headers using `ClientIPHeader` in your limiter option. - -### None of the above - -If none of the above solution are working, please use a custom `KeyGetter` in your middleware. - -You can use this excellent article to help you define the best strategy depending on your network topology and your security need: -https://adam-p.ca/blog/2022/03/x-forwarded-for/ - -If you have any idea/suggestions on how we could simplify this steps, don't hesitate to raise an issue. -We would like some feedback on how we could implement this steps in the Limiter API. - -Thank you. - -## Why Yet Another Package - -You could ask us: why yet another rate limit package? - -Because existing packages did not suit our needs. - -We tried a lot of alternatives: - -1. [Throttled][1]. This package uses the generic cell-rate algorithm. To cite the - documentation: _"The algorithm has been slightly modified from its usual form to - support limiting with an additional quantity parameter, such as for limiting the - number of bytes uploaded"_. It is brillant in term of algorithm but - documentation is quite unclear at the moment, we don't need _burst_ feature for - now, impossible to get a correct `After-Retry` (when limit exceeds, we can still - make a few requests, because of the max burst) and it only supports `http.Handler` - middleware (we use [Gin][4]). Currently, we only need to return `429` - and `X-Ratelimit-*` headers for `n reqs/duration`. - -2. [Speedbump][3]. Good package but maybe too lightweight. No `Reset` support, - only one middleware for [Gin][4] framework and too Redis-coupled. We rather - prefer to use a "store" approach. - -3. [Tollbooth][5]. Good one too but does both too much and too little. It limits by - remote IP, path, methods, custom headers and basic auth usernames... but does not - provide any Redis support (only _in-memory_) and a ready-to-go middleware that sets - `X-Ratelimit-*` headers. `tollbooth.LimitByRequest(limiter, r)` only returns an HTTP - code. - -4. [ratelimit][2]. Probably the closer to our needs but, once again, too - lightweight, no middleware available and not active (last commit was in August - 2014). Some parts of code (Redis) comes from this project. It should deserve much - more love. - -There are other many packages on GitHub but most are either too lightweight, too -old (only support old Go versions) or unmaintained. So that's why we decided to -create yet another one. - -## Contributing - -- Ping us on twitter: - - [@oibafsellig](https://twitter.com/oibafsellig) - - [@thoas](https://twitter.com/thoas) - - [@novln\_](https://twitter.com/novln_) -- Fork the [project](https://github.com/ulule/limiter) -- Fix [bugs](https://github.com/ulule/limiter/issues) - -Don't hesitate ;) - -[1]: https://github.com/throttled/throttled -[2]: https://github.com/r8k/ratelimit -[3]: https://github.com/etcinit/speedbump -[4]: https://github.com/gin-gonic/gin -[5]: https://github.com/didip/tollbooth -[6]: https://github.com/valyala/fasthttp -[godoc-url]: https://pkg.go.dev/github.com/ulule/limiter/v3 -[godoc-img]: https://pkg.go.dev/badge/github.com/ulule/limiter/v3 -[license-img]: https://img.shields.io/badge/license-MIT-blue.svg -[goreport-url]: https://goreportcard.com/report/github.com/ulule/limiter -[goreport-img]: https://goreportcard.com/badge/github.com/ulule/limiter -[circle-url]: https://circleci.com/gh/ulule/limiter/tree/master -[circle-img]: https://circleci.com/gh/ulule/limiter.svg?style=shield&circle-token=baf62ec320dd871b3a4a7e67fa99530fbc877c99 diff --git a/vendor/github.com/ulule/limiter/v3/defaults.go b/vendor/github.com/ulule/limiter/v3/defaults.go deleted file mode 100644 index 091edf3d2..000000000 --- a/vendor/github.com/ulule/limiter/v3/defaults.go +++ /dev/null @@ -1,15 +0,0 @@ -package limiter - -import "time" - -const ( - // DefaultPrefix is the default prefix to use for the key in the store. - DefaultPrefix = "limiter" - - // DefaultMaxRetry is the default maximum number of key retries under - // race condition (mainly used with database-based stores). - DefaultMaxRetry = 3 - - // DefaultCleanUpInterval is the default time duration for cleanup. - DefaultCleanUpInterval = 30 * time.Second -) diff --git a/vendor/github.com/ulule/limiter/v3/drivers/store/common/context.go b/vendor/github.com/ulule/limiter/v3/drivers/store/common/context.go deleted file mode 100644 index d181a460b..000000000 --- a/vendor/github.com/ulule/limiter/v3/drivers/store/common/context.go +++ /dev/null @@ -1,28 +0,0 @@ -package common - -import ( - "time" - - "github.com/ulule/limiter/v3" -) - -// GetContextFromState generate a new limiter.Context from given state. -func GetContextFromState(now time.Time, rate limiter.Rate, expiration time.Time, count int64) limiter.Context { - limit := rate.Limit - remaining := int64(0) - reached := true - - if count <= limit { - remaining = limit - count - reached = false - } - - reset := expiration.Unix() - - return limiter.Context{ - Limit: limit, - Remaining: remaining, - Reset: reset, - Reached: reached, - } -} diff --git a/vendor/github.com/ulule/limiter/v3/drivers/store/memory/cache.go b/vendor/github.com/ulule/limiter/v3/drivers/store/memory/cache.go deleted file mode 100644 index ce9accd9c..000000000 --- a/vendor/github.com/ulule/limiter/v3/drivers/store/memory/cache.go +++ /dev/null @@ -1,240 +0,0 @@ -package memory - -import ( - "runtime" - "sync" - "time" -) - -// Forked from https://github.com/patrickmn/go-cache - -// CacheWrapper is used to ensure that the underlying cleaner goroutine used to clean expired keys will not prevent -// Cache from being garbage collected. -type CacheWrapper struct { - *Cache -} - -// A cleaner will periodically delete expired keys from cache. -type cleaner struct { - interval time.Duration - stop chan bool -} - -// Run will periodically delete expired keys from given cache until GC notify that it should stop. -func (cleaner *cleaner) Run(cache *Cache) { - ticker := time.NewTicker(cleaner.interval) - for { - select { - case <-ticker.C: - cache.Clean() - case <-cleaner.stop: - ticker.Stop() - return - } - } -} - -// stopCleaner is a callback from GC used to stop cleaner goroutine. -func stopCleaner(wrapper *CacheWrapper) { - wrapper.cleaner.stop <- true - wrapper.cleaner = nil -} - -// startCleaner will start a cleaner goroutine for given cache. -func startCleaner(cache *Cache, interval time.Duration) { - cleaner := &cleaner{ - interval: interval, - stop: make(chan bool), - } - - cache.cleaner = cleaner - go cleaner.Run(cache) -} - -// Counter is a simple counter with an expiration. -type Counter struct { - mutex sync.RWMutex - value int64 - expiration int64 -} - -// Value returns the counter current value. -func (counter *Counter) Value() int64 { - counter.mutex.RLock() - defer counter.mutex.RUnlock() - return counter.value -} - -// Expiration returns the counter expiration. -func (counter *Counter) Expiration() int64 { - counter.mutex.RLock() - defer counter.mutex.RUnlock() - return counter.expiration -} - -// Expired returns true if the counter has expired. -func (counter *Counter) Expired() bool { - counter.mutex.RLock() - defer counter.mutex.RUnlock() - - return counter.expiration == 0 || time.Now().UnixNano() > counter.expiration -} - -// Load returns the value and the expiration of this counter. -// If the counter is expired, it will use the given expiration. -func (counter *Counter) Load(expiration int64) (int64, int64) { - counter.mutex.RLock() - defer counter.mutex.RUnlock() - - if counter.expiration == 0 || time.Now().UnixNano() > counter.expiration { - return 0, expiration - } - - return counter.value, counter.expiration -} - -// Increment increments given value on this counter. -// If the counter is expired, it will use the given expiration. -// It returns its current value and expiration. -func (counter *Counter) Increment(value int64, expiration int64) (int64, int64) { - counter.mutex.Lock() - defer counter.mutex.Unlock() - - if counter.expiration == 0 || time.Now().UnixNano() > counter.expiration { - counter.value = value - counter.expiration = expiration - return counter.value, counter.expiration - } - - counter.value += value - return counter.value, counter.expiration -} - -// Cache contains a collection of counters. -type Cache struct { - counters sync.Map - cleaner *cleaner -} - -// NewCache returns a new cache. -func NewCache(cleanInterval time.Duration) *CacheWrapper { - - cache := &Cache{} - wrapper := &CacheWrapper{Cache: cache} - - if cleanInterval > 0 { - startCleaner(cache, cleanInterval) - runtime.SetFinalizer(wrapper, stopCleaner) - } - - return wrapper -} - -// LoadOrStore returns the existing counter for the key if present. -// Otherwise, it stores and returns the given counter. -// The loaded result is true if the counter was loaded, false if stored. -func (cache *Cache) LoadOrStore(key string, counter *Counter) (*Counter, bool) { - val, loaded := cache.counters.LoadOrStore(key, counter) - if val == nil { - return counter, false - } - - actual := val.(*Counter) - return actual, loaded -} - -// Load returns the counter stored in the map for a key, or nil if no counter is present. -// The ok result indicates whether counter was found in the map. -func (cache *Cache) Load(key string) (*Counter, bool) { - val, ok := cache.counters.Load(key) - if val == nil || !ok { - return nil, false - } - actual := val.(*Counter) - return actual, true -} - -// Store sets the counter for a key. -func (cache *Cache) Store(key string, counter *Counter) { - cache.counters.Store(key, counter) -} - -// Delete deletes the value for a key. -func (cache *Cache) Delete(key string) { - cache.counters.Delete(key) -} - -// Range calls handler sequentially for each key and value present in the cache. -// If handler returns false, range stops the iteration. -func (cache *Cache) Range(handler func(key string, counter *Counter)) { - cache.counters.Range(func(k interface{}, v interface{}) bool { - if v == nil { - return true - } - - key := k.(string) - counter := v.(*Counter) - - handler(key, counter) - - return true - }) -} - -// Increment increments given value on key. -// If key is undefined or expired, it will create it. -func (cache *Cache) Increment(key string, value int64, duration time.Duration) (int64, time.Time) { - expiration := time.Now().Add(duration).UnixNano() - - // If counter is in cache, try to load it first. - counter, loaded := cache.Load(key) - if loaded { - value, expiration = counter.Increment(value, expiration) - return value, time.Unix(0, expiration) - } - - // If it's not in cache, try to atomically create it. - // We do that in two step to reduce memory allocation. - counter, loaded = cache.LoadOrStore(key, &Counter{ - mutex: sync.RWMutex{}, - value: value, - expiration: expiration, - }) - if loaded { - value, expiration = counter.Increment(value, expiration) - return value, time.Unix(0, expiration) - } - - // Otherwise, it has been created, return given value. - return value, time.Unix(0, expiration) -} - -// Get returns key's value and expiration. -func (cache *Cache) Get(key string, duration time.Duration) (int64, time.Time) { - expiration := time.Now().Add(duration).UnixNano() - - counter, ok := cache.Load(key) - if !ok { - return 0, time.Unix(0, expiration) - } - - value, expiration := counter.Load(expiration) - return value, time.Unix(0, expiration) -} - -// Clean will deleted any expired keys. -func (cache *Cache) Clean() { - cache.Range(func(key string, counter *Counter) { - if counter.Expired() { - cache.Delete(key) - } - }) -} - -// Reset changes the key's value and resets the expiration. -func (cache *Cache) Reset(key string, duration time.Duration) (int64, time.Time) { - cache.Delete(key) - - expiration := time.Now().Add(duration).UnixNano() - return 0, time.Unix(0, expiration) -} diff --git a/vendor/github.com/ulule/limiter/v3/drivers/store/memory/store.go b/vendor/github.com/ulule/limiter/v3/drivers/store/memory/store.go deleted file mode 100644 index 319983114..000000000 --- a/vendor/github.com/ulule/limiter/v3/drivers/store/memory/store.go +++ /dev/null @@ -1,75 +0,0 @@ -package memory - -import ( - "context" - "strings" - "time" - - "github.com/ulule/limiter/v3" - "github.com/ulule/limiter/v3/drivers/store/common" -) - -// Store is the in-memory store. -type Store struct { - // Prefix used for the key. - Prefix string - // cache used to store values in-memory. - cache *CacheWrapper -} - -// NewStore creates a new instance of memory store with defaults. -func NewStore() limiter.Store { - return NewStoreWithOptions(limiter.StoreOptions{ - Prefix: limiter.DefaultPrefix, - CleanUpInterval: limiter.DefaultCleanUpInterval, - }) -} - -// NewStoreWithOptions creates a new instance of memory store with options. -func NewStoreWithOptions(options limiter.StoreOptions) limiter.Store { - return &Store{ - Prefix: options.Prefix, - cache: NewCache(options.CleanUpInterval), - } -} - -// Get returns the limit for given identifier. -func (store *Store) Get(ctx context.Context, key string, rate limiter.Rate) (limiter.Context, error) { - count, expiration := store.cache.Increment(store.getCacheKey(key), 1, rate.Period) - - lctx := common.GetContextFromState(time.Now(), rate, expiration, count) - return lctx, nil -} - -// Increment increments the limit by given count & returns the new limit value for given identifier. -func (store *Store) Increment(ctx context.Context, key string, count int64, rate limiter.Rate) (limiter.Context, error) { - newCount, expiration := store.cache.Increment(store.getCacheKey(key), count, rate.Period) - - lctx := common.GetContextFromState(time.Now(), rate, expiration, newCount) - return lctx, nil -} - -// Peek returns the limit for given identifier, without modification on current values. -func (store *Store) Peek(ctx context.Context, key string, rate limiter.Rate) (limiter.Context, error) { - count, expiration := store.cache.Get(store.getCacheKey(key), rate.Period) - - lctx := common.GetContextFromState(time.Now(), rate, expiration, count) - return lctx, nil -} - -// Reset returns the limit for given identifier. -func (store *Store) Reset(ctx context.Context, key string, rate limiter.Rate) (limiter.Context, error) { - count, expiration := store.cache.Reset(store.getCacheKey(key), rate.Period) - - lctx := common.GetContextFromState(time.Now(), rate, expiration, count) - return lctx, nil -} - -// getCacheKey returns the full path for an identifier. -func (store *Store) getCacheKey(key string) string { - buffer := strings.Builder{} - buffer.WriteString(store.Prefix) - buffer.WriteString(":") - buffer.WriteString(key) - return buffer.String() -} diff --git a/vendor/github.com/ulule/limiter/v3/limiter.go b/vendor/github.com/ulule/limiter/v3/limiter.go deleted file mode 100644 index 1da6fceea..000000000 --- a/vendor/github.com/ulule/limiter/v3/limiter.go +++ /dev/null @@ -1,65 +0,0 @@ -package limiter - -import ( - "context" -) - -// ----------------------------------------------------------------- -// Context -// ----------------------------------------------------------------- - -// Context is the limit context. -type Context struct { - Limit int64 - Remaining int64 - Reset int64 - Reached bool -} - -// ----------------------------------------------------------------- -// Limiter -// ----------------------------------------------------------------- - -// Limiter is the limiter instance. -type Limiter struct { - Store Store - Rate Rate - Options Options -} - -// New returns an instance of Limiter. -func New(store Store, rate Rate, options ...Option) *Limiter { - opt := Options{ - IPv4Mask: DefaultIPv4Mask, - IPv6Mask: DefaultIPv6Mask, - TrustForwardHeader: false, - } - for _, o := range options { - o(&opt) - } - return &Limiter{ - Store: store, - Rate: rate, - Options: opt, - } -} - -// Get returns the limit for given identifier. -func (limiter *Limiter) Get(ctx context.Context, key string) (Context, error) { - return limiter.Store.Get(ctx, key, limiter.Rate) -} - -// Peek returns the limit for given identifier, without modification on current values. -func (limiter *Limiter) Peek(ctx context.Context, key string) (Context, error) { - return limiter.Store.Peek(ctx, key, limiter.Rate) -} - -// Reset sets the limit for given identifier to zero. -func (limiter *Limiter) Reset(ctx context.Context, key string) (Context, error) { - return limiter.Store.Reset(ctx, key, limiter.Rate) -} - -// Increment increments the limit by given count & gives back the new limit for given identifier -func (limiter *Limiter) Increment(ctx context.Context, key string, count int64) (Context, error) { - return limiter.Store.Increment(ctx, key, count, limiter.Rate) -} diff --git a/vendor/github.com/ulule/limiter/v3/network.go b/vendor/github.com/ulule/limiter/v3/network.go deleted file mode 100644 index 1fe7d8762..000000000 --- a/vendor/github.com/ulule/limiter/v3/network.go +++ /dev/null @@ -1,137 +0,0 @@ -package limiter - -import ( - "net" - "net/http" - "strings" -) - -var ( - // DefaultIPv4Mask defines the default IPv4 mask used to obtain user IP. - DefaultIPv4Mask = net.CIDRMask(32, 32) - // DefaultIPv6Mask defines the default IPv6 mask used to obtain user IP. - DefaultIPv6Mask = net.CIDRMask(128, 128) -) - -// GetIP returns IP address from request. -// If options is defined and either TrustForwardHeader is true or ClientIPHeader is defined, -// it will lookup IP in HTTP headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func (limiter *Limiter) GetIP(r *http.Request) net.IP { - return GetIP(r, limiter.Options) -} - -// GetIPWithMask returns IP address from request by applying a mask. -// If options is defined and either TrustForwardHeader is true or ClientIPHeader is defined, -// it will lookup IP in HTTP headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func (limiter *Limiter) GetIPWithMask(r *http.Request) net.IP { - return GetIPWithMask(r, limiter.Options) -} - -// GetIPKey extracts IP from request and returns hashed IP to use as store key. -// If options is defined and either TrustForwardHeader is true or ClientIPHeader is defined, -// it will lookup IP in HTTP headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func (limiter *Limiter) GetIPKey(r *http.Request) string { - return limiter.GetIPWithMask(r).String() -} - -// GetIP returns IP address from request. -// If options is defined and either TrustForwardHeader is true or ClientIPHeader is defined, -// it will lookup IP in HTTP headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func GetIP(r *http.Request, options ...Options) net.IP { - if len(options) >= 1 { - if options[0].ClientIPHeader != "" { - ip := getIPFromHeader(r, options[0].ClientIPHeader) - if ip != nil { - return ip - } - } - if options[0].TrustForwardHeader { - ip := getIPFromXFFHeader(r) - if ip != nil { - return ip - } - - ip = getIPFromHeader(r, "X-Real-IP") - if ip != nil { - return ip - } - } - } - - remoteAddr := strings.TrimSpace(r.RemoteAddr) - host, _, err := net.SplitHostPort(remoteAddr) - if err != nil { - return net.ParseIP(remoteAddr) - } - - return net.ParseIP(host) -} - -// GetIPWithMask returns IP address from request by applying a mask. -// If options is defined and either TrustForwardHeader is true or ClientIPHeader is defined, -// it will lookup IP in HTTP headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func GetIPWithMask(r *http.Request, options ...Options) net.IP { - if len(options) == 0 { - return GetIP(r) - } - - ip := GetIP(r, options[0]) - if ip.To4() != nil { - return ip.Mask(options[0].IPv4Mask) - } - if ip.To16() != nil { - return ip.Mask(options[0].IPv6Mask) - } - return ip -} - -func getIPFromXFFHeader(r *http.Request) net.IP { - headers := r.Header.Values("X-Forwarded-For") - if len(headers) == 0 { - return nil - } - - parts := []string{} - for _, header := range headers { - parts = append(parts, strings.Split(header, ",")...) - } - - for i := range parts { - part := strings.TrimSpace(parts[i]) - ip := net.ParseIP(part) - if ip != nil { - return ip - } - } - - return nil -} - -func getIPFromHeader(r *http.Request, name string) net.IP { - header := strings.TrimSpace(r.Header.Get(name)) - if header == "" { - return nil - } - - ip := net.ParseIP(header) - if ip != nil { - return ip - } - - return nil -} diff --git a/vendor/github.com/ulule/limiter/v3/options.go b/vendor/github.com/ulule/limiter/v3/options.go deleted file mode 100644 index d8a44eab3..000000000 --- a/vendor/github.com/ulule/limiter/v3/options.go +++ /dev/null @@ -1,61 +0,0 @@ -package limiter - -import ( - "net" -) - -// Option is a functional option. -type Option func(*Options) - -// Options are limiter options. -type Options struct { - // IPv4Mask defines the mask used to obtain a IPv4 address. - IPv4Mask net.IPMask - // IPv6Mask defines the mask used to obtain a IPv6 address. - IPv6Mask net.IPMask - // TrustForwardHeader enable parsing of X-Real-IP and X-Forwarded-For headers to obtain user IP. - // Please be advised that using this option could be insecure (ie: spoofed) if your reverse - // 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. - TrustForwardHeader bool - // ClientIPHeader defines a custom header (likely defined by your CDN or Cloud provider) to obtain user IP. - // If configured, this option will override "TrustForwardHeader" option. - // Please be advised that using this option could be insecure (ie: spoofed) if your reverse - // 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 -} - -// WithIPv4Mask will configure the limiter to use given mask for IPv4 address. -func WithIPv4Mask(mask net.IPMask) Option { - return func(o *Options) { - o.IPv4Mask = mask - } -} - -// WithIPv6Mask will configure the limiter to use given mask for IPv6 address. -func WithIPv6Mask(mask net.IPMask) Option { - return func(o *Options) { - o.IPv6Mask = mask - } -} - -// WithTrustForwardHeader will configure the limiter to trust X-Real-IP and X-Forwarded-For headers. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func WithTrustForwardHeader(enable bool) Option { - return func(o *Options) { - o.TrustForwardHeader = enable - } -} - -// WithClientIPHeader will configure the limiter to use a custom header to obtain user IP. -// Please be advised that using this option could be insecure (ie: spoofed) if your reverse -// 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. -func WithClientIPHeader(header string) Option { - return func(o *Options) { - o.ClientIPHeader = header - } -} diff --git a/vendor/github.com/ulule/limiter/v3/rate.go b/vendor/github.com/ulule/limiter/v3/rate.go deleted file mode 100644 index 46f656dd1..000000000 --- a/vendor/github.com/ulule/limiter/v3/rate.go +++ /dev/null @@ -1,53 +0,0 @@ -package limiter - -import ( - "strconv" - "strings" - "time" - - "github.com/pkg/errors" -) - -// Rate is the rate. -type Rate struct { - Formatted string - Period time.Duration - Limit int64 -} - -// NewRateFromFormatted returns the rate from the formatted version. -func NewRateFromFormatted(formatted string) (Rate, error) { - rate := Rate{} - - values := strings.Split(formatted, "-") - if len(values) != 2 { - return rate, errors.Errorf("incorrect format '%s'", formatted) - } - - periods := map[string]time.Duration{ - "S": time.Second, // Second - "M": time.Minute, // Minute - "H": time.Hour, // Hour - "D": time.Hour * 24, // Day - } - - limit, period := values[0], strings.ToUpper(values[1]) - - p, ok := periods[period] - if !ok { - return rate, errors.Errorf("incorrect period '%s'", period) - } - - l, err := strconv.ParseInt(limit, 10, 64) - if err != nil { - return rate, errors.Errorf("incorrect limit '%s'", limit) - } - - rate = Rate{ - Formatted: formatted, - Period: p, - Limit: l, - } - - return rate, nil -} diff --git a/vendor/github.com/ulule/limiter/v3/store.go b/vendor/github.com/ulule/limiter/v3/store.go deleted file mode 100644 index 9fdb3aa04..000000000 --- a/vendor/github.com/ulule/limiter/v3/store.go +++ /dev/null @@ -1,34 +0,0 @@ -package limiter - -import ( - "context" - "time" -) - -// Store is the common interface for limiter stores. -type Store interface { - // Get returns the limit for given identifier. - Get(ctx context.Context, key string, rate Rate) (Context, error) - // Peek returns the limit for given identifier, without modification on current values. - Peek(ctx context.Context, key string, rate Rate) (Context, error) - // Reset resets the limit to zero for given identifier. - Reset(ctx context.Context, key string, rate Rate) (Context, error) - // Increment increments the limit by given count & gives back the new limit for given identifier - Increment(ctx context.Context, key string, count int64, rate Rate) (Context, error) -} - -// StoreOptions are options for store. -type StoreOptions struct { - // Prefix is the prefix to use for the key. - Prefix string - - // MaxRetry is the maximum number of retry under race conditions on redis store. - // Deprecated: this option is no longer required since all operations are atomic now. - MaxRetry int - - // CleanUpInterval is the interval for cleanup (run garbage collection) on stale entries on memory store. - // Setting this to a low value will optimize memory consumption, but will likely - // reduce performance and increase lock contention. - // Setting this to a high value will maximum throughput, but will increase the memory footprint. - CleanUpInterval time.Duration -} |