init
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
package httpx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// JSON پاسخ JSON با کد وضعیت مینویسد.
|
||||
func JSON(w http.ResponseWriter, status int, body any) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(body)
|
||||
}
|
||||
|
||||
// Error پاسخ خطای استاندارد { "message": ... }.
|
||||
func Error(w http.ResponseWriter, status int, msg string) {
|
||||
JSON(w, status, map[string]string{"message": msg})
|
||||
}
|
||||
|
||||
// Throttle محدودکننده ساده in-memory بر اساس کلید (مثل IP یا موبایل).
|
||||
// معادل throttle:max,perMinutes در Laravel — بدون نیاز به Redis.
|
||||
type Throttle struct {
|
||||
mu sync.Mutex
|
||||
hits map[string][]time.Time
|
||||
max int
|
||||
window time.Duration
|
||||
}
|
||||
|
||||
func NewThrottle(max int, window time.Duration) *Throttle {
|
||||
return &Throttle{hits: make(map[string][]time.Time), max: max, window: window}
|
||||
}
|
||||
|
||||
// Allow بررسی میکند آیا کلید در پنجره زمانی مجاز است.
|
||||
func (t *Throttle) Allow(key string) bool {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
now := time.Now()
|
||||
cutoff := now.Add(-t.window)
|
||||
kept := t.hits[key][:0]
|
||||
for _, ts := range t.hits[key] {
|
||||
if ts.After(cutoff) {
|
||||
kept = append(kept, ts)
|
||||
}
|
||||
}
|
||||
if len(kept) >= t.max {
|
||||
t.hits[key] = kept
|
||||
return false
|
||||
}
|
||||
t.hits[key] = append(kept, now)
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user