first commit
This commit is contained in:
79
app/middleware/security.go
Normal file
79
app/middleware/security.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// DynamicCORS CORS davranisini ortama gore dinamik ayarlar.
|
||||
func DynamicCORS() gin.HandlerFunc {
|
||||
allowOrigin := os.Getenv("CORS_ALLOW_ORIGIN")
|
||||
if allowOrigin == "" {
|
||||
allowOrigin = "*"
|
||||
}
|
||||
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
type clientWindow struct {
|
||||
count int
|
||||
windowEnds time.Time
|
||||
}
|
||||
|
||||
// DynamicRateLimit IP bazli basit bir dakika penceresi limiti uygular.
|
||||
func DynamicRateLimit() gin.HandlerFunc {
|
||||
limit := 120
|
||||
if v := os.Getenv("RATE_LIMIT_RPM"); v != "" {
|
||||
if parsed, err := strconv.Atoi(v); err == nil && parsed > 0 {
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
|
||||
var mu sync.Mutex
|
||||
clients := map[string]*clientWindow{}
|
||||
|
||||
return func(c *gin.Context) {
|
||||
ip := c.ClientIP()
|
||||
now := time.Now()
|
||||
|
||||
mu.Lock()
|
||||
entry, ok := clients[ip]
|
||||
if !ok || now.After(entry.windowEnds) {
|
||||
entry = &clientWindow{count: 0, windowEnds: now.Add(time.Minute)}
|
||||
clients[ip] = entry
|
||||
}
|
||||
|
||||
entry.count++
|
||||
remaining := limit - entry.count
|
||||
resetIn := int(time.Until(entry.windowEnds).Seconds())
|
||||
mu.Unlock()
|
||||
|
||||
c.Header("X-RateLimit-Limit", strconv.Itoa(limit))
|
||||
if remaining < 0 {
|
||||
remaining = 0
|
||||
}
|
||||
c.Header("X-RateLimit-Remaining", strconv.Itoa(remaining))
|
||||
c.Header("X-RateLimit-Reset", strconv.Itoa(resetIn))
|
||||
|
||||
if entry.count > limit {
|
||||
c.AbortWithStatusJSON(http.StatusTooManyRequests, gin.H{"error": "rate limit asildi"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user