visitor.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package server
  2. import (
  3. "golang.org/x/time/rate"
  4. "heckel.io/ntfy/config"
  5. "heckel.io/ntfy/util"
  6. "sync"
  7. "time"
  8. )
  9. const (
  10. visitorExpungeAfter = 30 * time.Minute
  11. )
  12. // visitor represents an API user, and its associated rate.Limiter used for rate limiting
  13. type visitor struct {
  14. config *config.Config
  15. limiter *rate.Limiter
  16. subscriptions *util.Limiter
  17. seen time.Time
  18. mu sync.Mutex
  19. }
  20. func newVisitor(conf *config.Config) *visitor {
  21. return &visitor{
  22. config: conf,
  23. limiter: rate.NewLimiter(conf.VisitorRequestLimit, conf.VisitorRequestLimitBurst),
  24. subscriptions: util.NewLimiter(int64(conf.VisitorSubscriptionLimit)),
  25. seen: time.Now(),
  26. }
  27. }
  28. func (v *visitor) RequestAllowed() error {
  29. if !v.limiter.Allow() {
  30. return errHTTPTooManyRequests
  31. }
  32. return nil
  33. }
  34. func (v *visitor) AddSubscription() error {
  35. v.mu.Lock()
  36. defer v.mu.Unlock()
  37. if err := v.subscriptions.Add(1); err != nil {
  38. return errHTTPTooManyRequests
  39. }
  40. return nil
  41. }
  42. func (v *visitor) RemoveSubscription() {
  43. v.mu.Lock()
  44. defer v.mu.Unlock()
  45. v.subscriptions.Sub(1)
  46. }
  47. func (v *visitor) Keepalive() {
  48. v.mu.Lock()
  49. defer v.mu.Unlock()
  50. v.seen = time.Now()
  51. }
  52. func (v *visitor) Stale() bool {
  53. v.mu.Lock()
  54. defer v.mu.Unlock()
  55. return time.Since(v.seen) > visitorExpungeAfter
  56. }