FILE / Unmei/Backend

routes/ratelimiter.go

Исходный файл и его история в репозитории.
FILE 45bb32e7a6664f9c680c83ff29b4ed1b934d7912
Files
Backend/routes/ratelimiter.go
T
2025-03-12 16:30:40 +03:00

64 lines
1020 B
Go

package routes
import (
"net"
"net/http"
"sync"
"time"
"golang.org/x/time/rate"
)
type visitor struct {
limiter *rate.Limiter
lastSeen time.Time
}
var visitors = make(map[string]*visitor)
var mu sync.Mutex
func CleanupVisitors() {
for {
time.Sleep(time.Minute)
mu.Lock()
for ip, v := range visitors {
if time.Since(v.lastSeen) > time.Minute*3 {
delete(visitors, ip)
}
}
mu.Unlock()
}
}
func getVisitor(ip string) *rate.Limiter {
mu.Lock()
defer mu.Unlock()
v, exists := visitors[ip]
if !exists {
limiter := rate.NewLimiter(1, 20)
visitors[ip] = &visitor{limiter, time.Now()}
return limiter
}
v.lastSeen = time.Now()
return v.limiter
}
func LimitMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return
}
limiter := getVisitor(ip)
if !limiter.Allow() {
TooManyRequests.Ferror(w)
return
}
next.ServeHTTP(w, r)
})
}