diff options
author | Christopher Speller <crspeller@gmail.com> | 2016-05-12 15:08:58 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-05-12 16:37:29 -0400 |
commit | 84d2482ddbff9564c9ad75b2d30af66e3ddfd44d (patch) | |
tree | 8bfa567d2b6381f4a996ada2deff8a16aa85a3ac /Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go | |
parent | d1efb66ad7b017f0fbfe6f0c20843b30f396e504 (diff) | |
download | chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.gz chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.bz2 chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.zip |
Updating go depencancies. Switching to go1.6 vendoring (#2949)
Diffstat (limited to 'Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go')
-rw-r--r-- | Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go | 116 |
1 files changed, 0 insertions, 116 deletions
diff --git a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go b/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go deleted file mode 100644 index d7a7de6d7..000000000 --- a/Godeps/_workspace/src/gopkg.in/throttled/throttled.v1/rate.go +++ /dev/null @@ -1,116 +0,0 @@ -package throttled - -import ( - "math" - "net/http" - "strconv" - "time" -) - -// Static check to ensure that rateLimiter implements Limiter. -var _ Limiter = (*rateLimiter)(nil) - -// RateLimit creates a throttler that limits the number of requests allowed -// in a certain time window defined by the Quota q. The q parameter specifies -// the requests per time window, and it is silently set to at least 1 request -// and at least a 1 second window if it is less than that. The time window -// starts when the first request is made outside an existing window. Fractions -// of seconds are not supported, they are truncated. -// -// The vary parameter indicates what criteria should be used to group requests -// for which the limit must be applied (ex.: rate limit based on the remote address). -// See varyby.go for the various options. -// -// The specified store is used to keep track of the request count and the -// time remaining in the window. The throttled package comes with some stores -// in the throttled/store package. Custom stores can be created too, by implementing -// the Store interface. -// -// Requests that bust the rate limit are denied access and go through the denied handler, -// which may be specified on the Throttler and that defaults to the package-global -// variable DefaultDeniedHandler. -// -// The rate limit throttler sets the following headers on the response: -// -// X-RateLimit-Limit : quota -// X-RateLimit-Remaining : number of requests remaining in the current window -// X-RateLimit-Reset : seconds before a new window -// -// Additionally, if the request was denied access, the following header is added: -// -// Retry-After : seconds before the caller should retry -// -func RateLimit(q Quota, vary *VaryBy, store Store) *Throttler { - // Extract requests and window - reqs, win := q.Quota() - - // Create and return the throttler - return &Throttler{ - limiter: &rateLimiter{ - reqs: reqs, - window: win, - vary: vary, - store: store, - }, - } -} - -// The rate limiter implements limiting the request to a certain quota -// based on the vary-by criteria. State is saved in the store. -type rateLimiter struct { - reqs int - window time.Duration - vary *VaryBy - store Store -} - -// Start initializes the limiter for execution. -func (r *rateLimiter) Start() { - if r.reqs < 1 { - r.reqs = 1 - } - if r.window < time.Second { - r.window = time.Second - } -} - -// Limit is called for each request to the throttled handler. It checks if -// the request can go through and signals it via the returned channel. -// It returns an error if the operation fails. -func (r *rateLimiter) Limit(w http.ResponseWriter, req *http.Request) (<-chan bool, error) { - // Create return channel and initialize - ch := make(chan bool, 1) - ok := true - key := r.vary.Key(req) - - // Get the current count and remaining seconds - cnt, secs, err := r.store.Incr(key, r.window) - // Handle the possible situations: error, begin new window, or increment current window. - switch { - case err != nil && err != ErrNoSuchKey: - // An unexpected error occurred - return nil, err - case err == ErrNoSuchKey || secs <= 0: - // Reset counter - if err := r.store.Reset(key, r.window); err != nil { - return nil, err - } - cnt = 1 - secs = int(r.window.Seconds()) - default: - // If the limit is reached, deny access - if cnt > r.reqs { - ok = false - } - } - // Set rate-limit headers - w.Header().Add("X-RateLimit-Limit", strconv.Itoa(r.reqs)) - w.Header().Add("X-RateLimit-Remaining", strconv.Itoa(int(math.Max(float64(r.reqs-cnt), 0)))) - w.Header().Add("X-RateLimit-Reset", strconv.Itoa(secs)) - if !ok { - w.Header().Add("Retry-After", strconv.Itoa(secs)) - } - // Send response via the return channel - ch <- ok - return ch, nil -} |