feat: strict ratelimit

This commit is contained in:
httpjamesm 2022-12-28 00:00:17 -05:00
parent 076f1387f0
commit 8b46beb1dd
2 changed files with 46 additions and 0 deletions

View File

@ -14,7 +14,9 @@ func main() {
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./public")
r.Use(gin.Recovery())
r.Use(middleware.OptionsMiddleware())
r.Use(middleware.Ratelimit())
r.GET("/robots.txt", func(c *gin.Context) {
c.String(200, "User-agent: *\nDisallow: /")

View File

@ -0,0 +1,44 @@
package middleware
import (
"sync"
"time"
"github.com/gin-gonic/gin"
)
var ipMap = sync.Map{}
func Ratelimit() gin.HandlerFunc {
return func(c *gin.Context) {
ip := c.ClientIP()
// log request count as the value, ip as key
// if the ip is not in the map, create a new entry with a value of 1
// if they exceed 30 requests in 1 minute, return a 429
// get the value from the map
val, ok := ipMap.Load(ip)
if !ok {
// if the ip is not in the map, create a new entry with a value of 1
ipMap.Store(ip, 1)
c.Next()
return
}
// if the ip is in the map, increment the value
ipMap.Store(ip, val.(int)+1)
// if they exceed 30 requests in 1 minute, return a 429
if val.(int) > 30 {
c.String(429, "429 Too Many Requests")
c.Abort()
return
}
// delete the ip from the map after 1 minute
time.AfterFunc(time.Minute, func() {
ipMap.Delete(ip)
})
}
}