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:
2026-08-22 00:34:51 +01:00
co-authored by Sisyphus
parent 37f6723d9e
commit d03ce79c19
2 changed files with 14 additions and 3 deletions
+4 -2
View File
@@ -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
View File
@@ -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 {