Functional Weave
Code in Rust

http.retry-after@1.0.0

README.md

1,880 bytes · view raw

# http.retry-after

How long to wait before trying again, from a `Retry-After` header on a 429
(Too Many Requests) or 503 response:

```
retryAfterSeconds("120", now)                             # 120
retryAfterSeconds("Wed, 21 Oct 2015 07:28:00 GMT", 1445412420)  # 60
retryAfterSeconds(null, now)                              # null: no header
retryAfterSeconds("soon", now)                            # null: not a Retry-After
```

RFC 9110 section 10.2.3 allows two forms:

- **delay-seconds**: one or more ASCII digits (`120`, `0`, `007`). Signs,
  fractions, other scripts' digits and more than nine digits (31 years) are
  not a wait anyone meant, so they are null.
- **HTTP-date**, in the preferred IMF-fixdate form
  (`Sun, 06 Nov 1994 08:49:37 GMT`, section 5.6.7): exactly that layout, day
  and month names in English with that capitalisation, `GMT` in capitals, a
  real calendar date (29 February only in a leap year, via
  `dates.is-leap-year`), hours 00-23 and seconds 00-59. It is turned into
  seconds from `now` through `time.iso-to-unix`; a date already past is 0.
  The day name is not checked against the date. The obsolete RFC 850 and
  asctime forms, which a recipient "SHOULD" accept, are refused here: nothing
  still sends them, and each is a two-digit-year or zone ambiguity.

Spaces and tabs around the value are ignored (HTTP's optional whitespace);
anything else, a newline included, is null. Null is a signal, not an error:
the caller falls back to its own backoff rather than trusting a garbled
header. The caller reads the clock and passes `now` in whole Unix seconds;
a fraction throws "now must be a whole number of seconds".

Pair it with `time.countdown(now + seconds, now)` to show the wait ticking
down.

Source: RFC 9110, HTTP Semantics, sections 10.2.3 (Retry-After) and 5.6.7
(Date/Time Formats), https://www.rfc-editor.org/rfc/rfc9110.