summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/throttled/throttled.v2
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2018-04-16 05:37:14 -0700
committerJoram Wilander <jwawilander@gmail.com>2018-04-16 08:37:14 -0400
commit6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch)
tree3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/gopkg.in/throttled/throttled.v2
parentbf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff)
downloadchat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/gopkg.in/throttled/throttled.v2')
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/.travis.yml18
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/Makefile2
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/README.md83
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go59
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/doc.go2
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/example_test.go103
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/http_test.go99
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/rate.go17
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/rate_test.go128
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go32
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go2
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go40
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go168
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go85
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go2
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go176
-rw-r--r--vendor/gopkg.in/throttled/throttled.v2/varyby_test.go58
17 files changed, 75 insertions, 999 deletions
diff --git a/vendor/gopkg.in/throttled/throttled.v2/.travis.yml b/vendor/gopkg.in/throttled/throttled.v2/.travis.yml
index 0c19e2cd5..29225d7af 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/.travis.yml
+++ b/vendor/gopkg.in/throttled/throttled.v2/.travis.yml
@@ -3,13 +3,8 @@ sudo: false
language: go
go:
- - 1.7
- - 1.8
- - 1.9
- # 1.x builds the latest in that series. Also try to add other versions here
- # as they come up so that we're pretty sure that we're maintaining
- # backwards compatibility.
- - 1.x
+ - 1.3
+ - tip
notifications:
email: false
@@ -17,6 +12,13 @@ notifications:
services:
- redis-server
-install: make get-deps
+install:
+ - make get-deps
+ # Move to the gopkg location that rather than the default clone location
+ # otherwise Go 1.4+ complains about incorrect import paths.
+ - export GOPKG_DIR=$GOPATH/src/gopkg.in/throttled
+ - mkdir -p $GOPKG_DIR
+ - mv $TRAVIS_BUILD_DIR $GOPKG_DIR/throttled.v2
+ - cd $GOPKG_DIR/throttled.v2
script: make
diff --git a/vendor/gopkg.in/throttled/throttled.v2/Makefile b/vendor/gopkg.in/throttled/throttled.v2/Makefile
index d6e33c516..cfc235c31 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/Makefile
+++ b/vendor/gopkg.in/throttled/throttled.v2/Makefile
@@ -11,7 +11,9 @@ bench:
lint:
gofmt -l .
+ifneq ($(TRAVIS_GO_VERSION),1.3) # go vet doesn't play nicely on 1.3
go vet ./...
+endif
which golint # Fail if golint doesn't exist
-golint . # Don't fail on golint warnings themselves
-golint store # Don't fail on golint warnings themselves
diff --git a/vendor/gopkg.in/throttled/throttled.v2/README.md b/vendor/gopkg.in/throttled/throttled.v2/README.md
index d0e0609a5..b18dcbcc6 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/README.md
+++ b/vendor/gopkg.in/throttled/throttled.v2/README.md
@@ -1,7 +1,7 @@
-# Throttled [![build status](https://secure.travis-ci.org/throttled/throttled.svg)](https://travis-ci.org/throttled/throttled) [![GoDoc](https://godoc.org/github.com/throttled/throttled?status.svg)](https://godoc.org/github.com/throttled/throttled)
+# Throttled [![build status](https://secure.travis-ci.org/throttled/throttled.png)](https://travis-ci.org/throttled/throttled) [![GoDoc](https://godoc.org/gopkg.in/throttled/throttled.v2?status.png)](https://godoc.org/gopkg.in/throttled/throttled.v2)
-Package throttled implements rate limiting using the [generic cell rate
-algorithm][gcra] to limit access to resources such as HTTP endpoints.
+Package throttled implements rate limiting access to resources such as
+HTTP endpoints.
The 2.0.0 release made some major changes to the throttled API. If
this change broke your code in problematic ways or you wish a feature
@@ -11,9 +11,16 @@ what our users need. Thanks!
## Installation
-```sh
-go get -u github.com/throttled/throttled`
-```
+throttled uses gopkg.in for semantic versioning:
+`go get gopkg.in/throttled/throttled.v2`
+
+As of July 27, 2015, the package is located under its own Github
+organization. Please adjust your imports to
+`gopkg.in/throttled/throttled.v2`.
+
+The 1.x release series is compatible with the original, unversioned
+library written by [Martin Angers][puerkitobio]. There is a
+[blog post explaining that version's usage on 0value.com][blog].
## Documentation
@@ -22,39 +29,57 @@ example demonstrates the usage of HTTPLimiter for rate-limiting access
to an http.Handler to 20 requests per path per minute with bursts of
up to 5 additional requests:
-```go
-store, err := memstore.New(65536)
-if err != nil {
- log.Fatal(err)
-}
+ store, err := memstore.New(65536)
+ if err != nil {
+ log.Fatal(err)
+ }
-quota := throttled.RateQuota{throttled.PerMin(20), 5}
-rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
-if err != nil {
- log.Fatal(err)
-}
+ quota := throttled.RateQuota{throttled.PerMin(20), 5}
+ rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
+ if err != nil {
+ log.Fatal(err)
+ }
-httpRateLimiter := throttled.HTTPRateLimiter{
- RateLimiter: rateLimiter,
- VaryBy: &throttled.VaryBy{Path: true},
-}
+ httpRateLimiter := throttled.HTTPRateLimiter{
+ RateLimiter: rateLimiter,
+ VaryBy: &throttled.VaryBy{Path: true},
+ }
-http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler))
-```
+ http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler))
+
+## Contributing
-## Related Projects
+Since throttled uses gopkg.in for versioning, running `go get` against
+a fork or cloning from Github to the default path will break
+imports. Instead, use the following process for setting up your
+environment and contributing:
+
+```sh
+# Retrieve the source and dependencies.
+go get gopkg.in/throttled/throttled.v2/...
+
+# Fork the project on Github. For all following directions replace
+# <username> with your Github username. Add your fork as a remote.
+cd $GOPATH/src/gopkg.in/throttled/throttled.v2
+git remote add fork git@github.com:<username>/throttled.git
+
+# Create a branch, make your changes, test them and commit.
+git checkout -b my-new-feature
+# <do some work>
+make test
+git commit -a
+git push -u fork my-new-feature
+```
-See [throttled/gcra][throttled-gcra] for a list of other projects related to
-rate limiting and GCRA.
+When your changes are ready, [open a pull request][pr] using "compare
+across forks".
## License
-The [BSD 3-clause license][bsd]. Copyright (c) 2014 Martin Angers and contributors.
+The [BSD 3-clause license][bsd]. Copyright (c) 2014 Martin Angers and Contributors.
[blog]: http://0value.com/throttled--guardian-of-the-web-server
[bsd]: https://opensource.org/licenses/BSD-3-Clause
-[doc]: https://godoc.org/github.com/throttled/throttled
-[gcra]: https://en.wikipedia.org/wiki/Generic_cell_rate_algorithm
+[doc]: https://godoc.org/gopkg.in/throttled/throttled.v2
[puerkitobio]: https://github.com/puerkitobio/
[pr]: https://github.com/throttled/throttled/compare
-[throttled-gcra]: https://github.com/throttled/gcra
diff --git a/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go b/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go
deleted file mode 100644
index e0453d78f..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package throttled_test
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/throttled/throttled"
- "github.com/throttled/throttled/store"
-)
-
-// Ensure that the current implementation remains compatible with the
-// supported but deprecated usage until the next major version.
-func TestDeprecatedUsage(t *testing.T) {
- // Declare interfaces to statically check that names haven't changed
- var st throttled.Store
- var thr *throttled.Throttler
- var q throttled.Quota
-
- st = store.NewMemStore(100)
- vary := &throttled.VaryBy{Path: true}
- q = throttled.PerMin(2)
- thr = throttled.RateLimit(q, vary, st)
- handler := thr.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(200)
- }))
-
- cases := []struct {
- path string
- code int
- headers map[string]string
- }{
- {"/foo", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "1", "X-Ratelimit-Reset": "30"}},
- {"/foo", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "0", "X-Ratelimit-Reset": "60"}},
- {"/foo", 429, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "0", "X-Ratelimit-Reset": "60", "Retry-After": "30"}},
- {"/bar", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "1", "X-Ratelimit-Reset": "30"}},
- }
-
- for i, c := range cases {
- req, err := http.NewRequest("GET", c.path, nil)
- if err != nil {
- t.Fatal(err)
- }
-
- rr := httptest.NewRecorder()
- handler.ServeHTTP(rr, req)
- if have, want := rr.Code, c.code; have != want {
- t.Errorf("Expected request %d at %s to return %d but got %d",
- i, c.path, want, have)
- }
-
- for name, want := range c.headers {
- if have := rr.HeaderMap.Get(name); have != want {
- t.Errorf("Expected request %d at %s to have header '%s: %s' but got '%s'",
- i, c.path, name, want, have)
- }
- }
- }
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/doc.go b/vendor/gopkg.in/throttled/throttled.v2/doc.go
index cb14a65a6..302c2bed7 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/doc.go
+++ b/vendor/gopkg.in/throttled/throttled.v2/doc.go
@@ -1,3 +1,3 @@
// Package throttled implements rate limiting access to resources such
// as HTTP endpoints.
-package throttled // import "github.com/throttled/throttled"
+package throttled // import "gopkg.in/throttled/throttled.v2"
diff --git a/vendor/gopkg.in/throttled/throttled.v2/example_test.go b/vendor/gopkg.in/throttled/throttled.v2/example_test.go
deleted file mode 100644
index 7c4c5df14..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/example_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package throttled_test
-
-import (
- "fmt"
- "log"
- "net/http"
-
- "github.com/throttled/throttled"
- "github.com/throttled/throttled/store/memstore"
-)
-
-var myHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("hi there!"))
-})
-
-// ExampleHTTPRateLimiter demonstrates the usage of HTTPRateLimiter
-// for rate-limiting access to an http.Handler to 20 requests per path
-// per minute with a maximum burst of 5 requests.
-func ExampleHTTPRateLimiter() {
- store, err := memstore.New(65536)
- if err != nil {
- log.Fatal(err)
- }
-
- // Maximum burst of 5 which refills at 20 tokens per minute.
- quota := throttled.RateQuota{throttled.PerMin(20), 5}
-
- rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
- if err != nil {
- log.Fatal(err)
- }
-
- httpRateLimiter := throttled.HTTPRateLimiter{
- RateLimiter: rateLimiter,
- VaryBy: &throttled.VaryBy{Path: true},
- }
-
- http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler))
-}
-
-// Demonstrates direct use of GCRARateLimiter's RateLimit function (and the
-// more general RateLimiter interface). This should be used anywhere where
-// granular control over rate limiting is required.
-func ExampleGCRARateLimiter() {
- store, err := memstore.New(65536)
- if err != nil {
- log.Fatal(err)
- }
-
- // Maximum burst of 5 which refills at 1 token per hour.
- quota := throttled.RateQuota{throttled.PerHour(1), 5}
-
- rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
- if err != nil {
- log.Fatal(err)
- }
-
- // Bucket according to the number i / 10 (so 1 falls into the bucket 0
- // while 11 falls into the bucket 1). This has the effect of allowing a
- // burst of 5 plus 1 (a single emission interval) on every ten iterations
- // of the loop. See the output for better clarity here.
- //
- // We also refill the bucket at 1 token per hour, but that has no effect
- // for the purposes of this example.
- for i := 0; i < 20; i++ {
- bucket := fmt.Sprintf("by-order:%v", i/10)
-
- limited, result, err := rateLimiter.RateLimit(bucket, 1)
- if err != nil {
- log.Fatal(err)
- }
-
- if limited {
- fmt.Printf("Iteration %2v; bucket %v: FAILED. Rate limit exceeded.\n",
- i, bucket)
- } else {
- fmt.Printf("Iteration %2v; bucket %v: Operation successful (remaining=%v).\n",
- i, bucket, result.Remaining)
- }
- }
-
- // Output:
- // Iteration 0; bucket by-order:0: Operation successful (remaining=5).
- // Iteration 1; bucket by-order:0: Operation successful (remaining=4).
- // Iteration 2; bucket by-order:0: Operation successful (remaining=3).
- // Iteration 3; bucket by-order:0: Operation successful (remaining=2).
- // Iteration 4; bucket by-order:0: Operation successful (remaining=1).
- // Iteration 5; bucket by-order:0: Operation successful (remaining=0).
- // Iteration 6; bucket by-order:0: FAILED. Rate limit exceeded.
- // Iteration 7; bucket by-order:0: FAILED. Rate limit exceeded.
- // Iteration 8; bucket by-order:0: FAILED. Rate limit exceeded.
- // Iteration 9; bucket by-order:0: FAILED. Rate limit exceeded.
- // Iteration 10; bucket by-order:1: Operation successful (remaining=5).
- // Iteration 11; bucket by-order:1: Operation successful (remaining=4).
- // Iteration 12; bucket by-order:1: Operation successful (remaining=3).
- // Iteration 13; bucket by-order:1: Operation successful (remaining=2).
- // Iteration 14; bucket by-order:1: Operation successful (remaining=1).
- // Iteration 15; bucket by-order:1: Operation successful (remaining=0).
- // Iteration 16; bucket by-order:1: FAILED. Rate limit exceeded.
- // Iteration 17; bucket by-order:1: FAILED. Rate limit exceeded.
- // Iteration 18; bucket by-order:1: FAILED. Rate limit exceeded.
- // Iteration 19; bucket by-order:1: FAILED. Rate limit exceeded.
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/http_test.go b/vendor/gopkg.in/throttled/throttled.v2/http_test.go
deleted file mode 100644
index 52a706e2d..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/http_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package throttled_test
-
-import (
- "errors"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/throttled/throttled"
-)
-
-type stubLimiter struct {
-}
-
-func (sl *stubLimiter) RateLimit(key string, quantity int) (bool, throttled.RateLimitResult, error) {
- switch key {
- case "limit":
- return true, throttled.RateLimitResult{-1, -1, -1, time.Minute}, nil
- case "error":
- return false, throttled.RateLimitResult{}, errors.New("stubLimiter error")
- default:
- return false, throttled.RateLimitResult{1, 2, time.Minute, -1}, nil
- }
-}
-
-type pathGetter struct{}
-
-func (*pathGetter) Key(r *http.Request) string {
- return r.URL.Path
-}
-
-type httpTestCase struct {
- path string
- code int
- headers map[string]string
-}
-
-func TestHTTPRateLimiter(t *testing.T) {
- limiter := throttled.HTTPRateLimiter{
- RateLimiter: &stubLimiter{},
- VaryBy: &pathGetter{},
- }
-
- handler := limiter.RateLimit(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(200)
- }))
-
- runHTTPTestCases(t, handler, []httpTestCase{
- {"ok", 200, map[string]string{"X-Ratelimit-Limit": "1", "X-Ratelimit-Remaining": "2", "X-Ratelimit-Reset": "60"}},
- {"error", 500, map[string]string{}},
- {"limit", 429, map[string]string{"Retry-After": "60"}},
- })
-}
-
-func TestCustomHTTPRateLimiterHandlers(t *testing.T) {
- limiter := throttled.HTTPRateLimiter{
- RateLimiter: &stubLimiter{},
- VaryBy: &pathGetter{},
- DeniedHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- http.Error(w, "custom limit exceeded", 400)
- }),
- Error: func(w http.ResponseWriter, r *http.Request, err error) {
- http.Error(w, "custom internal error", 501)
- },
- }
-
- handler := limiter.RateLimit(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(200)
- }))
-
- runHTTPTestCases(t, handler, []httpTestCase{
- {"limit", 400, map[string]string{}},
- {"error", 501, map[string]string{}},
- })
-}
-
-func runHTTPTestCases(t *testing.T, h http.Handler, cs []httpTestCase) {
- for i, c := range cs {
- req, err := http.NewRequest("GET", c.path, nil)
- if err != nil {
- t.Fatal(err)
- }
-
- rr := httptest.NewRecorder()
- h.ServeHTTP(rr, req)
- if have, want := rr.Code, c.code; have != want {
- t.Errorf("Expected request %d at %s to return %d but got %d",
- i, c.path, want, have)
- }
-
- for name, want := range c.headers {
- if have := rr.HeaderMap.Get(name); have != want {
- t.Errorf("Expected request %d at %s to have header '%s: %s' but got '%s'",
- i, c.path, name, want, have)
- }
- }
- }
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/rate.go b/vendor/gopkg.in/throttled/throttled.v2/rate.go
index 649287beb..8c11cdb47 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/rate.go
+++ b/vendor/gopkg.in/throttled/throttled.v2/rate.go
@@ -84,18 +84,17 @@ type Rate struct {
// RateQuota describes the number of requests allowed per time period.
// MaxRate specified the maximum sustained rate of requests and must
-// be greater than zero. MaxBurst defines the number of requests that
+// be greater than zero. MaxBurst defines the number of requests that
// will be allowed to exceed the rate in a single burst and must be
// greater than or equal to zero.
//
// Rate{PerSec(1), 0} would mean that after each request, no more
-// requests will be permitted for that client for one second.
-// Rate{PerSec(2), 0} permits one request per 0.5 seconds rather than
-// two requests in one second. In practice, you probably want to set
-// MaxBurst >0 to provide some flexibility to clients that only need
-// to make a handful of requests. In fact a MaxBurst of zero will
-// *never* permit a request with a quantity greater than one because
-// it will immediately exceed the limit.
+// requests will be permitted for that client for one second. In
+// practice, you probably want to set MaxBurst >0 to provide some
+// flexibility to clients that only need to make a handful of
+// requests. In fact a MaxBurst of zero will *never* permit a request
+// with a quantity greater than one because it will immediately exceed
+// the limit.
type RateQuota struct {
MaxRate Rate
MaxBurst int
@@ -119,12 +118,10 @@ func PerDay(n int) Rate { return Rate{24 * time.Hour / time.Duration(n), n} }
// as for limiting the number of bytes uploaded.
type GCRARateLimiter struct {
limit int
-
// Think of the DVT as our flexibility:
// How far can you deviate from the nominal equally spaced schedule?
// If you like leaky buckets, think about it as the size of your bucket.
delayVariationTolerance time.Duration
-
// Think of the emission interval as the time between events
// in the nominal equally spaced schedule. If you like leaky buckets,
// think of it as how frequently the bucket leaks one unit.
diff --git a/vendor/gopkg.in/throttled/throttled.v2/rate_test.go b/vendor/gopkg.in/throttled/throttled.v2/rate_test.go
deleted file mode 100644
index a1a5f621e..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/rate_test.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package throttled_test
-
-import (
- "testing"
- "time"
-
- "github.com/throttled/throttled"
- "github.com/throttled/throttled/store/memstore"
-)
-
-const deniedStatus = 429
-
-type testStore struct {
- store throttled.GCRAStore
-
- clock time.Time
- failUpdates bool
-}
-
-func (ts *testStore) GetWithTime(key string) (int64, time.Time, error) {
- v, _, e := ts.store.GetWithTime(key)
- return v, ts.clock, e
-}
-
-func (ts *testStore) SetIfNotExistsWithTTL(key string, value int64, ttl time.Duration) (bool, error) {
- if ts.failUpdates {
- return false, nil
- }
- return ts.store.SetIfNotExistsWithTTL(key, value, ttl)
-}
-
-func (ts *testStore) CompareAndSwapWithTTL(key string, old, new int64, ttl time.Duration) (bool, error) {
- if ts.failUpdates {
- return false, nil
- }
- return ts.store.CompareAndSwapWithTTL(key, old, new, ttl)
-}
-
-func TestRateLimit(t *testing.T) {
- limit := 5
- rq := throttled.RateQuota{throttled.PerSec(1), limit - 1}
- start := time.Unix(0, 0)
- cases := []struct {
- now time.Time
- volume, remaining int
- reset, retry time.Duration
- limited bool
- }{
- // You can never make a request larger than the maximum
- 0: {start, 6, 5, 0, -1, true},
- // Rate limit normal requests appropriately
- 1: {start, 1, 4, time.Second, -1, false},
- 2: {start, 1, 3, 2 * time.Second, -1, false},
- 3: {start, 1, 2, 3 * time.Second, -1, false},
- 4: {start, 1, 1, 4 * time.Second, -1, false},
- 5: {start, 1, 0, 5 * time.Second, -1, false},
- 6: {start, 1, 0, 5 * time.Second, time.Second, true},
- 7: {start.Add(3000 * time.Millisecond), 1, 2, 3000 * time.Millisecond, -1, false},
- 8: {start.Add(3100 * time.Millisecond), 1, 1, 3900 * time.Millisecond, -1, false},
- 9: {start.Add(4000 * time.Millisecond), 1, 1, 4000 * time.Millisecond, -1, false},
- 10: {start.Add(8000 * time.Millisecond), 1, 4, 1000 * time.Millisecond, -1, false},
- 11: {start.Add(9500 * time.Millisecond), 1, 4, 1000 * time.Millisecond, -1, false},
- // Zero-volume request just peeks at the state
- 12: {start.Add(9500 * time.Millisecond), 0, 4, time.Second, -1, false},
- // High-volume request uses up more of the limit
- 13: {start.Add(9500 * time.Millisecond), 2, 2, 3 * time.Second, -1, false},
- // Large requests cannot exceed limits
- 14: {start.Add(9500 * time.Millisecond), 5, 2, 3 * time.Second, 3 * time.Second, true},
- }
-
- mst, err := memstore.New(0)
- if err != nil {
- t.Fatal(err)
- }
- st := testStore{store: mst}
-
- rl, err := throttled.NewGCRARateLimiter(&st, rq)
- if err != nil {
- t.Fatal(err)
- }
-
- // Start the server
- for i, c := range cases {
- st.clock = c.now
-
- limited, context, err := rl.RateLimit("foo", c.volume)
- if err != nil {
- t.Fatalf("%d: %#v", i, err)
- }
-
- if limited != c.limited {
- t.Errorf("%d: expected Limited to be %t but got %t", i, c.limited, limited)
- }
-
- if have, want := context.Limit, limit; have != want {
- t.Errorf("%d: expected Limit to be %d but got %d", i, want, have)
- }
-
- if have, want := context.Remaining, c.remaining; have != want {
- t.Errorf("%d: expected Remaining to be %d but got %d", i, want, have)
- }
-
- if have, want := context.ResetAfter, c.reset; have != want {
- t.Errorf("%d: expected ResetAfter to be %s but got %s", i, want, have)
- }
-
- if have, want := context.RetryAfter, c.retry; have != want {
- t.Errorf("%d: expected RetryAfter to be %d but got %d", i, want, have)
- }
- }
-}
-
-func TestRateLimitUpdateFailures(t *testing.T) {
- rq := throttled.RateQuota{throttled.PerSec(1), 1}
- mst, err := memstore.New(0)
- if err != nil {
- t.Fatal(err)
- }
- st := testStore{store: mst, failUpdates: true}
- rl, err := throttled.NewGCRARateLimiter(&st, rq)
- if err != nil {
- t.Fatal(err)
- }
-
- if _, _, err := rl.RateLimit("foo", 1); err == nil {
- t.Error("Expected limiting to fail when store updates fail")
- }
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go b/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go
deleted file mode 100644
index 0492ba89e..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Package store contains deprecated aliases for subpackages
-package store // import "github.com/throttled/throttled/store"
-
-import (
- "github.com/garyburd/redigo/redis"
-
- "github.com/throttled/throttled/store/memstore"
- "github.com/throttled/throttled/store/redigostore"
-)
-
-// DEPRECATED. NewMemStore is a compatible alias for mem.New
-func NewMemStore(maxKeys int) *memstore.MemStore {
- st, err := memstore.New(maxKeys)
- if err != nil {
- // As of this writing, `lru.New` can only return an error if you pass
- // maxKeys <= 0 so this should never occur.
- panic(err)
- }
- return st
-}
-
-// DEPRECATED. NewMemStore is a compatible alias for redis.New
-func NewRedisStore(pool *redis.Pool, keyPrefix string, db int) *redigostore.RedigoStore {
- st, err := redigostore.New(pool, keyPrefix, db)
- if err != nil {
- // As of this writing, creating a Redis store never returns an error
- // so this should be safe while providing some ability to return errors
- // in the future.
- panic(err)
- }
- return st
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go
index 352232958..5d8fee8b5 100644
--- a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go
+++ b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go
@@ -1,5 +1,5 @@
// Package memstore offers an in-memory store implementation for throttled.
-package memstore // import "github.com/throttled/throttled/store/memstore"
+package memstore // import "gopkg.in/throttled/throttled.v2/store/memstore"
import (
"sync"
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go
deleted file mode 100644
index 27b1c9b95..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package memstore_test
-
-import (
- "testing"
-
- "github.com/throttled/throttled/store/memstore"
- "github.com/throttled/throttled/store/storetest"
-)
-
-func TestMemStoreLRU(t *testing.T) {
- st, err := memstore.New(10)
- if err != nil {
- t.Fatal(err)
- }
- storetest.TestGCRAStore(t, st)
-}
-
-func TestMemStoreUnlimited(t *testing.T) {
- st, err := memstore.New(10)
- if err != nil {
- t.Fatal(err)
- }
- storetest.TestGCRAStore(t, st)
-}
-
-func BenchmarkMemStoreLRU(b *testing.B) {
- st, err := memstore.New(10)
- if err != nil {
- b.Fatal(err)
- }
- storetest.BenchmarkGCRAStore(b, st)
-}
-
-func BenchmarkMemStoreUnlimited(b *testing.B) {
- st, err := memstore.New(0)
- if err != nil {
- b.Fatal(err)
- }
- storetest.BenchmarkGCRAStore(b, st)
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go
deleted file mode 100644
index 03acbcab0..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Package redigostore offers Redis-based store implementation for throttled using redigo.
-package redigostore // import "github.com/throttled/throttled/store/redigostore"
-
-import (
- "strings"
- "time"
-
- "github.com/garyburd/redigo/redis"
-)
-
-const (
- redisCASMissingKey = "key does not exist"
- redisCASScript = `
-local v = redis.call('get', KEYS[1])
-if v == false then
- return redis.error_reply("key does not exist")
-end
-if v ~= ARGV[1] then
- return 0
-end
-redis.call('setex', KEYS[1], ARGV[3], ARGV[2])
-return 1
-`
-)
-
-// RedigoStore implements a Redis-based store using redigo.
-type RedigoStore struct {
- pool *redis.Pool
- prefix string
- db int
-}
-
-// New creates a new Redis-based store, using the provided pool to get
-// its connections. The keys will have the specified keyPrefix, which
-// may be an empty string, and the database index specified by db will
-// be selected to store the keys. Any updating operations will reset
-// the key TTL to the provided value rounded down to the nearest
-// second. Depends on Redis 2.6+ for EVAL support.
-func New(pool *redis.Pool, keyPrefix string, db int) (*RedigoStore, error) {
- return &RedigoStore{
- pool: pool,
- prefix: keyPrefix,
- db: db,
- }, nil
-}
-
-// GetWithTime returns the value of the key if it is in the store
-// or -1 if it does not exist. It also returns the current time at
-// the redis server to microsecond precision.
-func (r *RedigoStore) GetWithTime(key string) (int64, time.Time, error) {
- var now time.Time
-
- key = r.prefix + key
-
- conn, err := r.getConn()
- if err != nil {
- return 0, now, err
- }
- defer conn.Close()
-
- conn.Send("TIME")
- conn.Send("GET", key)
- conn.Flush()
- timeReply, err := redis.Values(conn.Receive())
- if err != nil {
- return 0, now, err
- }
-
- var s, us int64
- if _, err := redis.Scan(timeReply, &s, &us); err != nil {
- return 0, now, err
- }
- now = time.Unix(s, us*int64(time.Microsecond))
-
- v, err := redis.Int64(conn.Receive())
- if err == redis.ErrNil {
- return -1, now, nil
- } else if err != nil {
- return 0, now, err
- }
-
- return v, now, nil
-}
-
-// SetIfNotExistsWithTTL sets the value of key only if it is not
-// already set in the store it returns whether a new value was set.
-// If a new value was set, the ttl in the key is also set, though this
-// operation is not performed atomically.
-func (r *RedigoStore) SetIfNotExistsWithTTL(key string, value int64, ttl time.Duration) (bool, error) {
- key = r.prefix + key
-
- conn, err := r.getConn()
- if err != nil {
- return false, err
- }
- defer conn.Close()
-
- v, err := redis.Int64(conn.Do("SETNX", key, value))
- if err != nil {
- return false, err
- }
-
- updated := v == 1
-
- ttlSeconds := int(ttl.Seconds())
-
- // An `EXPIRE 0` will delete the key immediately, so make sure that we set
- // expiry for a minimum of one second out so that our results stay in the
- // store.
- if ttlSeconds < 1 {
- ttlSeconds = 1
- }
-
- if _, err := conn.Do("EXPIRE", key, ttlSeconds); err != nil {
- return updated, err
- }
-
- return updated, nil
-}
-
-// CompareAndSwapWithTTL atomically compares the value at key to the
-// old value. If it matches, it sets it to the new value and returns
-// true. Otherwise, it returns false. If the key does not exist in the
-// store, it returns false with no error. If the swap succeeds, the
-// ttl for the key is updated atomically.
-func (r *RedigoStore) CompareAndSwapWithTTL(key string, old, new int64, ttl time.Duration) (bool, error) {
- key = r.prefix + key
- conn, err := r.getConn()
- if err != nil {
- return false, err
- }
- defer conn.Close()
-
- ttlSeconds := int(ttl.Seconds())
-
- // An `EXPIRE 0` will delete the key immediately, so make sure that we set
- // expiry for a minimum of one second out so that our results stay in the
- // store.
- if ttlSeconds < 1 {
- ttlSeconds = 1
- }
-
- swapped, err := redis.Bool(conn.Do("EVAL", redisCASScript, 1, key, old, new, ttlSeconds))
- if err != nil {
- if strings.Contains(err.Error(), redisCASMissingKey) {
- return false, nil
- }
-
- return false, err
- }
-
- return swapped, nil
-}
-
-// Select the specified database index.
-func (r *RedigoStore) getConn() (redis.Conn, error) {
- conn := r.pool.Get()
-
- // Select the specified database
- if r.db > 0 {
- if _, err := redis.String(conn.Do("SELECT", r.db)); err != nil {
- conn.Close()
- return nil, err
- }
- }
-
- return conn, nil
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go
deleted file mode 100644
index ee9e2904d..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package redigostore_test
-
-import (
- "testing"
- "time"
-
- "github.com/garyburd/redigo/redis"
-
- "github.com/throttled/throttled/store/redigostore"
- "github.com/throttled/throttled/store/storetest"
-)
-
-const (
- redisTestDB = 1
- redisTestPrefix = "throttled:"
-)
-
-func getPool() *redis.Pool {
- pool := &redis.Pool{
- MaxIdle: 3,
- IdleTimeout: 30 * time.Second,
- Dial: func() (redis.Conn, error) {
- return redis.Dial("tcp", ":6379")
- },
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
- _, err := c.Do("PING")
- return err
- },
- }
- return pool
-}
-
-func TestRedisStore(t *testing.T) {
- c, st := setupRedis(t, 0)
- defer c.Close()
- defer clearRedis(c)
-
- clearRedis(c)
- storetest.TestGCRAStore(t, st)
- storetest.TestGCRAStoreTTL(t, st)
-}
-
-func BenchmarkRedisStore(b *testing.B) {
- c, st := setupRedis(b, 0)
- defer c.Close()
- defer clearRedis(c)
-
- storetest.BenchmarkGCRAStore(b, st)
-}
-
-func clearRedis(c redis.Conn) error {
- keys, err := redis.Values(c.Do("KEYS", redisTestPrefix+"*"))
- if err != nil {
- return err
- }
-
- if _, err := redis.Int(c.Do("DEL", keys...)); err != nil {
- return err
- }
-
- return nil
-}
-
-func setupRedis(tb testing.TB, ttl time.Duration) (redis.Conn, *redigostore.RedigoStore) {
- pool := getPool()
- c := pool.Get()
-
- if _, err := redis.String(c.Do("PING")); err != nil {
- c.Close()
- tb.Skip("redis server not available on localhost port 6379")
- }
-
- if _, err := redis.String(c.Do("SELECT", redisTestDB)); err != nil {
- c.Close()
- tb.Fatal(err)
- }
-
- st, err := redigostore.New(pool, redisTestPrefix, redisTestDB)
- if err != nil {
- c.Close()
- tb.Fatal(err)
- }
-
- return c, st
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go
deleted file mode 100644
index 405c59a12..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package storetest provides a helper for testing throttled stores.
-package storetest // import "github.com/throttled/throttled/store/storetest"
diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go
deleted file mode 100644
index 2233ebdfb..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Package storetest provides a helper for testing throttled stores.
-package storetest // import "github.com/throttled/throttled/store/storetest"
-
-import (
- "math/rand"
- "strconv"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/throttled/throttled"
-)
-
-// TestGCRAStore tests the behavior of a GCRAStore implementation for
-// compliance with the throttled API. It does not require support
-// for TTLs.
-func TestGCRAStore(t *testing.T, st throttled.GCRAStore) {
- // GetWithTime a missing key
- if have, _, err := st.GetWithTime("foo"); err != nil {
- t.Fatal(err)
- } else if have != -1 {
- t.Errorf("expected GetWithTime to return -1 for a missing key but got %d", have)
- }
-
- // SetIfNotExists on a new key
- want := int64(1)
-
- if set, err := st.SetIfNotExistsWithTTL("foo", want, 0); err != nil {
- t.Fatal(err)
- } else if !set {
- t.Errorf("expected SetIfNotExists on an empty key to succeed")
- }
-
- before := time.Now()
-
- if have, now, err := st.GetWithTime("foo"); err != nil {
- t.Fatal(err)
- } else if have != want {
- t.Errorf("expected GetWithTime to return %d but got %d", want, have)
- } else if now.UnixNano() <= 0 {
- t.Errorf("expected GetWithTime to return a time representable representable as a positive int64 of nanoseconds since the epoch")
- } else if now.Before(before) || now.After(time.Now()) {
- // Note that we make the assumption here that the store is running on
- // the same machine as this test and thus shares a clock. This can be a
- // little tricky in the case of Redis, which could be running
- // elsewhere. The test assumes that it's running either locally on on
- // Travis (where currently the Redis is available on localhost). If new
- // test environments are procured, this may need to be revisited.
- t.Errorf("expected GetWithTime to return a time between the time before the call and the time after the call")
- }
-
- // SetIfNotExists on an existing key
- if set, err := st.SetIfNotExistsWithTTL("foo", 123, 0); err != nil {
- t.Fatal(err)
- } else if set {
- t.Errorf("expected SetIfNotExists on an existing key to fail")
- }
-
- if have, _, err := st.GetWithTime("foo"); err != nil {
- t.Fatal(err)
- } else if have != want {
- t.Errorf("expected GetWithTime to return %d but got %d", want, have)
- }
-
- // SetIfNotExists on a different key
- if set, err := st.SetIfNotExistsWithTTL("bar", 456, 0); err != nil {
- t.Fatal(err)
- } else if !set {
- t.Errorf("expected SetIfNotExists on an empty key to succeed")
- }
-
- // Returns the false on a missing key
- if swapped, err := st.CompareAndSwapWithTTL("baz", 1, 2, 0); err != nil {
- t.Fatal(err)
- } else if swapped {
- t.Errorf("expected CompareAndSwap to fail on a missing key")
- }
-
- // Test a successful CAS
- want = int64(2)
-
- if swapped, err := st.CompareAndSwapWithTTL("foo", 1, want, 0); err != nil {
- t.Fatal(err)
- } else if !swapped {
- t.Errorf("expected CompareAndSwap to succeed")
- }
-
- if have, _, err := st.GetWithTime("foo"); err != nil {
- t.Fatal(err)
- } else if have != want {
- t.Errorf("expected GetWithTime to return %d but got %d", want, have)
- }
-
- // Test an unsuccessful CAS
- if swapped, err := st.CompareAndSwapWithTTL("foo", 1, 2, 0); err != nil {
- t.Fatal(err)
- } else if swapped {
- t.Errorf("expected CompareAndSwap to fail")
- }
-
- if have, _, err := st.GetWithTime("foo"); err != nil {
- t.Fatal(err)
- } else if have != want {
- t.Errorf("expected GetWithTime to return %d but got %d", want, have)
- }
-}
-
-// TestGCRAStoreTTL tests the behavior of TTLs in a GCRAStore implementation.
-func TestGCRAStoreTTL(t *testing.T, st throttled.GCRAStore) {
- ttl := time.Second
- want := int64(1)
- key := "ttl"
-
- if _, err := st.SetIfNotExistsWithTTL(key, want, ttl); err != nil {
- t.Fatal(err)
- }
-
- if have, _, err := st.GetWithTime(key); err != nil {
- t.Fatal(err)
- } else if have != want {
- t.Errorf("expected GetWithTime to return %d, got %d", want, have)
- }
-
- // I can't think of a generic way to test expiration without a sleep
- time.Sleep(ttl + time.Millisecond)
-
- if have, _, err := st.GetWithTime(key); err != nil {
- t.Fatal(err)
- } else if have != -1 {
- t.Errorf("expected GetWithTime to fail on an expired key but got %d", have)
- }
-}
-
-// BenchmarkGCRAStore runs parallel benchmarks against a GCRAStore implementation.
-// Aside from being useful for performance testing, this is useful for finding
-// race conditions with the Go race detector.
-func BenchmarkGCRAStore(b *testing.B, st throttled.GCRAStore) {
- seed := int64(42)
- var attempts, updates int64
-
- b.RunParallel(func(pb *testing.PB) {
- // We need atomic behavior around the RNG or go detects a race in the test
- delta := int64(1)
- seedValue := atomic.AddInt64(&seed, delta) - delta
- gen := rand.New(rand.NewSource(seedValue))
-
- for pb.Next() {
- key := strconv.FormatInt(gen.Int63n(50), 10)
-
- var v int64
- var updated bool
-
- v, _, err := st.GetWithTime(key)
- if v == -1 {
- updated, err = st.SetIfNotExistsWithTTL(key, gen.Int63(), 0)
- if err != nil {
- b.Error(err)
- }
- } else if err != nil {
- b.Error(err)
- } else {
- updated, err = st.CompareAndSwapWithTTL(key, v, gen.Int63(), 0)
- if err != nil {
- b.Error(err)
- }
- }
-
- atomic.AddInt64(&attempts, 1)
- if updated {
- atomic.AddInt64(&updates, 1)
- }
- }
- })
-
- b.Logf("%d/%d update operations succeeed", updates, attempts)
-}
diff --git a/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go b/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go
deleted file mode 100644
index 6ad48ea19..000000000
--- a/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package throttled_test
-
-import (
- "net/http"
- "net/url"
- "testing"
-
- "github.com/throttled/throttled"
-)
-
-func TestVaryBy(t *testing.T) {
- u, err := url.Parse("http://localhost/test/path?q=s")
- if err != nil {
- panic(err)
- }
- ck := &http.Cookie{Name: "ssn", Value: "test"}
- cases := []struct {
- vb *throttled.VaryBy
- r *http.Request
- k string
- }{
- 0: {nil, &http.Request{}, ""},
- 1: {&throttled.VaryBy{RemoteAddr: true}, &http.Request{RemoteAddr: "::"}, "::\n"},
- 2: {
- &throttled.VaryBy{Method: true, Path: true},
- &http.Request{Method: "POST", URL: u},
- "post\n/test/path\n",
- },
- 3: {
- &throttled.VaryBy{Headers: []string{"Content-length"}},
- &http.Request{Header: http.Header{"Content-Type": []string{"text/plain"}, "Content-Length": []string{"123"}}},
- "123\n",
- },
- 4: {
- &throttled.VaryBy{Separator: ",", Method: true, Headers: []string{"Content-length"}, Params: []string{"q", "user"}},
- &http.Request{Method: "GET", Header: http.Header{"Content-Type": []string{"text/plain"}, "Content-Length": []string{"123"}}, Form: url.Values{"q": []string{"s"}, "pwd": []string{"secret"}, "user": []string{"test"}}},
- "get,123,s,test,",
- },
- 5: {
- &throttled.VaryBy{Cookies: []string{"ssn"}},
- &http.Request{Header: http.Header{"Cookie": []string{ck.String()}}},
- "test\n",
- },
- 6: {
- &throttled.VaryBy{Cookies: []string{"ssn"}, RemoteAddr: true, Custom: func(r *http.Request) string {
- return "blah"
- }},
- &http.Request{Header: http.Header{"Cookie": []string{ck.String()}}},
- "blah",
- },
- }
- for i, c := range cases {
- got := c.vb.Key(c.r)
- if got != c.k {
- t.Errorf("%d: expected '%s' (%d), got '%s' (%d)", i, c.k, len(c.k), got, len(got))
- }
- }
-}