From 6e2cb00008cbf09e556b00f87603797fcaa47e09 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 16 Apr 2018 05:37:14 -0700 Subject: Depenancy upgrades and movign to dep. (#8630) --- vendor/gopkg.in/throttled/throttled.v2/.travis.yml | 18 ++- vendor/gopkg.in/throttled/throttled.v2/Makefile | 2 + vendor/gopkg.in/throttled/throttled.v2/README.md | 83 ++++++---- .../throttled/throttled.v2/deprecated_test.go | 59 ------- vendor/gopkg.in/throttled/throttled.v2/doc.go | 2 +- .../throttled/throttled.v2/example_test.go | 103 ------------ .../gopkg.in/throttled/throttled.v2/http_test.go | 99 ------------ vendor/gopkg.in/throttled/throttled.v2/rate.go | 17 +- .../gopkg.in/throttled/throttled.v2/rate_test.go | 128 --------------- .../throttled/throttled.v2/store/deprecated.go | 32 ---- .../throttled.v2/store/memstore/memstore.go | 2 +- .../throttled.v2/store/memstore/memstore_test.go | 40 ----- .../throttled.v2/store/redigostore/redigostore.go | 168 -------------------- .../store/redigostore/redigostore_test.go | 85 ---------- .../throttled/throttled.v2/store/storetest/doc.go | 2 - .../throttled.v2/store/storetest/storetest.go | 176 --------------------- .../gopkg.in/throttled/throttled.v2/varyby_test.go | 58 ------- 17 files changed, 75 insertions(+), 999 deletions(-) delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/example_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/http_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/rate_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/varyby_test.go (limited to 'vendor/gopkg.in/throttled/throttled.v2') 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 +# 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:/throttled.git + +# Create a branch, make your changes, test them and commit. +git checkout -b my-new-feature +# +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)) - } - } -} -- cgit v1.2.3-1-g7c22