package app import ( "context" "crypto/sha256" "fmt" "net" "net/http" "strings" "time" ) func (a *App) allowRequest(ctx context.Context, action, subject string, limit int, window time.Duration) bool { if limit < 1 || window < time.Second { return false } windowSeconds := int64(window / time.Second) slot := time.Now().Unix() / windowSeconds key := sha256.Sum256([]byte(fmt.Sprintf("%s|%s|%d", action, subject, slot))) expiresAt := time.Unix((slot+1)*windowSeconds, 0).Add(time.Minute) _, err := a.db.ExecContext(ctx, `INSERT INTO api_rate_limits(bucket_key,action_name,hits,expires_at) VALUES(?,?,1,?) ON DUPLICATE KEY UPDATE hits=hits+1,expires_at=VALUES(expires_at)`, key[:], action, expiresAt) if err != nil { return false } var hits int if err = a.db.QueryRowContext(ctx, `SELECT hits FROM api_rate_limits WHERE bucket_key=?`, key[:]).Scan(&hits); err != nil { return false } if key[0] == 0 { _, _ = a.db.ExecContext(ctx, `DELETE FROM api_rate_limits WHERE expires_at