7 "golang.org/x/time/rate"
10 type BucketLimiter struct {
14 bucketMu sync.Mutex // protects the following
15 buckets map[string]*rate.Limiter
18 func NewBucketLimiter(freq, burst int) *BucketLimiter {
19 return &BucketLimiter{
20 freq: rate.Limit(freq),
22 buckets: make(map[string]*rate.Limiter),
26 func (b *BucketLimiter) Allow(id string) bool {
27 return b.bucket(id).Allow()
30 func (b *BucketLimiter) bucket(id string) *rate.Limiter {
32 bucket, ok := b.buckets[id]
34 bucket = rate.NewLimiter(b.freq, b.burst)
35 b.buckets[id] = bucket
44 f func(*http.Request) string
46 limiter *BucketLimiter
49 func Handler(next, limited http.Handler, freq, burst int, f func(*http.Request) string) http.Handler {
54 limiter: NewBucketLimiter(freq, burst),
58 func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
60 if !h.limiter.Allow(id) {
61 h.limited.ServeHTTP(w, r)
64 h.next.ServeHTTP(w, r)
67 func RemoteAddrID(r *http.Request) string {
71 func AuthUserID(r *http.Request) string {
72 user, _, _ := r.BasicAuth()