You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
921 B
55 lines
921 B
|
8 years ago
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/labstack/echo"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
rateLimit = 20 // times per rateLimitInterval
|
||
|
|
rateLimitInterval = 1 * time.Hour
|
||
|
|
)
|
||
|
|
|
||
|
|
var accesses = &sync.Map{}
|
||
|
|
|
||
|
|
type access struct {
|
||
|
|
count int
|
||
|
|
timestamp time.Time
|
||
|
|
}
|
||
|
|
|
||
|
|
func legitAccess(c echo.Context) bool {
|
||
|
|
ip := c.Request().RemoteAddr
|
||
|
|
aRaw, found := accesses.Load(ip)
|
||
|
|
var a *access
|
||
|
|
if found {
|
||
|
|
a, _ = aRaw.(*access)
|
||
|
|
} else {
|
||
|
|
a = &access{}
|
||
|
|
}
|
||
|
|
a.count++
|
||
|
|
a.timestamp = time.Now()
|
||
|
|
accesses.Store(ip, a)
|
||
|
|
return a.count < rateLimit
|
||
|
|
}
|
||
|
|
|
||
|
|
func cleanAccessRegistry(logger echo.Logger) {
|
||
|
|
for {
|
||
|
|
time.Sleep(rateLimitInterval)
|
||
|
|
t, e := 0, 0
|
||
|
|
accesses.Range(func(ip, aRaw interface{}) bool {
|
||
|
|
t++
|
||
|
|
a, _ := aRaw.(*access)
|
||
|
|
if a.timestamp.Add(rateLimitInterval).Before(time.Now()) {
|
||
|
|
accesses.Delete(ip)
|
||
|
|
e++
|
||
|
|
}
|
||
|
|
return true
|
||
|
|
})
|
||
|
|
if e > 0 {
|
||
|
|
logger.Infof("cleaned up %d/%d outdated accesses", e, t)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|