util.go 785 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. package main
  2. import (
  3. "net"
  4. "sync"
  5. "time"
  6. "golang.org/x/time/rate"
  7. )
  8. // Rate limiters per IP with automatic cleanup
  9. var (
  10. limiters sync.Map
  11. lastClean = time.Now()
  12. )
  13. func rateLimitAllow(addr string) bool {
  14. // Extract just the IP
  15. ip := addr
  16. if host, _, err := net.SplitHostPort(addr); err == nil {
  17. ip = host
  18. }
  19. // Clean old entries every hour
  20. if time.Since(lastClean) > time.Hour {
  21. lastClean = time.Now()
  22. limiters.Range(func(key, value interface{}) bool {
  23. if l, ok := value.(*rate.Limiter); ok && l.Tokens() >= 10 {
  24. limiters.Delete(key)
  25. }
  26. return true
  27. })
  28. }
  29. // Get or create limiter for this IP
  30. limiterInterface, _ := limiters.LoadOrStore(ip, rate.NewLimiter(100.0/60, 10))
  31. limiter := limiterInterface.(*rate.Limiter)
  32. return limiter.Allow()
  33. }