fix: rate limiter memory pruning in Check(), services error leakage replaced with generic messages
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -523,7 +523,8 @@ func ServicesEligibleForUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to get user data: "+err.Error(), http.StatusInternalServerError)
|
log.Printf("Failed to get user data for %s: %v", userID, err)
|
||||||
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +551,8 @@ func ServicesEligibleForUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
rows, err := db.Conn.Query(r.Context(), query)
|
rows, err := db.Conn.Query(r.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to fetch services: "+err.Error(), http.StatusInternalServerError)
|
log.Printf("Failed to fetch services: %v", err)
|
||||||
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|||||||
+10
-1
@@ -50,7 +50,7 @@ func NewProgressiveRateLimiter() *ProgressiveRateLimiter {
|
|||||||
// Check returns the delay in milliseconds. Returns 0 if no delay needed.
|
// Check returns the delay in milliseconds. Returns 0 if no delay needed.
|
||||||
// Strategy:
|
// Strategy:
|
||||||
// - Count requests in last 5 seconds (burst): allow up to 30
|
// - Count requests in last 5 seconds (burst): allow up to 30
|
||||||
// - Count requests in last 60 seconds (sustained): allow up to 60
|
// - Count requests in last 60 seconds (sustained): allow up to 120
|
||||||
// - Only delay when BOTH windows are exceeded (high sustained rate with recent bursts)
|
// - Only delay when BOTH windows are exceeded (high sustained rate with recent bursts)
|
||||||
// - Progressive: once throttled, delay increases with sustained rate
|
// - Progressive: once throttled, delay increases with sustained rate
|
||||||
func (prl *ProgressiveRateLimiter) Check(ip string) (delayMs int) {
|
func (prl *ProgressiveRateLimiter) Check(ip string) (delayMs int) {
|
||||||
@@ -68,6 +68,15 @@ func (prl *ProgressiveRateLimiter) Check(ip string) (delayMs int) {
|
|||||||
|
|
||||||
state.timestamps = append(state.timestamps, now)
|
state.timestamps = append(state.timestamps, now)
|
||||||
|
|
||||||
|
cutoff := now.Add(-60 * time.Second)
|
||||||
|
pruned := state.timestamps[:0]
|
||||||
|
for _, t := range state.timestamps {
|
||||||
|
if t.After(cutoff) {
|
||||||
|
pruned = append(pruned, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.timestamps = pruned
|
||||||
|
|
||||||
burstCutoff := now.Add(-5 * time.Second)
|
burstCutoff := now.Add(-5 * time.Second)
|
||||||
burstCount := 0
|
burstCount := 0
|
||||||
for _, t := range state.timestamps {
|
for _, t := range state.timestamps {
|
||||||
|
|||||||
Reference in New Issue
Block a user