writeTooManyRequests sends a 429 response with a Retry-After header (delay-seconds form, RFC 7231 §7.1.3). Callers should pass the duration returned from Limiter.AllowWithRetryAfter so the value reflects when the next slot actually opens up. Callers must return after invoking this — it writes the fu
(w http.ResponseWriter, retryAfter time.Duration, msg string)
| 76 | // reflects when the next slot actually opens up. Callers must return |
| 77 | // after invoking this — it writes the full response. |
| 78 | func writeTooManyRequests(w http.ResponseWriter, retryAfter time.Duration, msg string) { |
| 79 | secs := int(retryAfter.Round(time.Second).Seconds()) |
| 80 | if secs < 1 { |
| 81 | secs = 1 |
| 82 | } |
| 83 | w.Header().Set("Retry-After", strconv.Itoa(secs)) |
| 84 | http.Error(w, msg, http.StatusTooManyRequests) |
| 85 | } |
| 86 | |
| 87 | // Standard request body limits. Most agent/domain payloads are tiny; |
| 88 | // /send carries a full email body which can include large HTML + |