parseRetryAfter extracts a retry duration from rate-limit response headers. It checks Retry-After (seconds) first, then the named resetHeader (unix timestamp). Returns zero if no recognizable header is present.
(h http.Header, resetHeader string, clk quartz.Clock)
| 207 | // resetHeader (unix timestamp). Returns zero if no recognizable header |
| 208 | // is present. |
| 209 | func parseRetryAfter(h http.Header, resetHeader string, clk quartz.Clock) time.Duration { |
| 210 | if clk == nil { |
| 211 | clk = quartz.NewReal() |
| 212 | } |
| 213 | // Retry-After header: seconds until retry. |
| 214 | if ra := h.Get("Retry-After"); ra != "" { |
| 215 | if secs, err := strconv.Atoi(ra); err == nil { |
| 216 | return time.Duration(secs) * time.Second |
| 217 | } |
| 218 | } |
| 219 | // Reset header: unix timestamp. We compute the duration from now |
| 220 | // according to the caller's clock. |
| 221 | if reset := h.Get(resetHeader); reset != "" { |
| 222 | if ts, err := strconv.ParseInt(reset, 10, 64); err == nil { |
| 223 | return time.Unix(ts, 0).Sub(clk.Now()) |
| 224 | } |
| 225 | } |
| 226 | return 0 |
| 227 | } |
| 228 | |
| 229 | // checkRateLimitError returns a *RateLimitError when resp indicates a |
| 230 | // rate limit (HTTP 403 or 429) with recognizable retry headers; |