-
Notifications
You must be signed in to change notification settings - Fork 30
/
limiter.go
48 lines (41 loc) · 1.33 KB
/
limiter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package limiter
import (
"net/http"
"time"
"github.com/didip/tollbooth"
"github.com/didip/tollbooth/limiter"
)
// rateLimiter represents custom wrapper above limiter.Limiter.
type rateLimit struct {
Limiter *limiter.Limiter
RateLimit bool
RequestsPerSecond float64
}
// userRateLimit represents application level limiter.
var userRateLimit *rateLimit
func (rl *rateLimit) init() {
if rl.RequestsPerSecond == 0 {
rl.RateLimit = false
return
}
rl.RateLimit = true
rl.Limiter = tollbooth.NewLimiter(rl.RequestsPerSecond, &limiter.ExpirableOptions{DefaultExpirationTTL: time.Hour}).
SetIPLookups([]string{"RemoteAddr", "X-Forwarded-For", "X-Real-IP"}).
SetMethods([]string{"GET", "POST", "PUT", "DELETE"})
}
// ConfigRateLimits configures rate limits used in app.
//
// Should be called only once while application starting process.
func ConfigRateLimits(limit float64) {
userRateLimit = &rateLimit{RequestsPerSecond: limit}
userRateLimit.init()
}
// UserRateLimit is a middleware that performs rate-limiting given request handler function.
func UserRateLimit(handler http.HandlerFunc) http.HandlerFunc {
if !userRateLimit.RateLimit {
return handler
}
return func(writer http.ResponseWriter, request *http.Request) {
tollbooth.LimitFuncHandler(userRateLimit.Limiter, handler).ServeHTTP(writer, request)
}
}