Retry-After Header Parser With Clock Skew

Parse Retry-After delay-seconds or HTTP-date values into milliseconds, clamp them to a maximum and correct for server clock skew.

JavascriptResilience

Code

snippet
const MAX_DELAY_MS = 24 * 60 * 60 * 1000;

export function parseRetryAfter(value, options = {}) {
  if (typeof value !== "string") return null;
  const { now = Date.now(), serverDate, maxMs = MAX_DELAY_MS } = options;
  if (!Number.isFinite(now)) throw new RangeError("now must be a finite timestamp");
  if (!Number.isFinite(maxMs) || maxMs < 0) {
    throw new RangeError("maxMs must be a non-negative finite number");
  }
  if (serverDate !== undefined && !Number.isFinite(serverDate)) {
    throw new RangeError("serverDate must be a finite timestamp");
  }

  const trimmed = value.trim();
  if (trimmed === "") return null;

  if (/^\d+$/.test(trimmed)) {
    const seconds = Number(trimmed);
    if (!Number.isSafeInteger(seconds)) return null;
    return Math.min(seconds * 1000, maxMs);
  }

  const target = Date.parse(trimmed);
  if (Number.isNaN(target)) return null;
  const reference = serverDate === undefined ? now : serverDate;
  return Math.min(Math.max(0, target - reference), maxMs);
}