Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 14x 14x 14x 14x 14x 14x 14x 14x 139x 16x 124x 17x 4x 9x 139x 139x 139x 14x 14x 14x 366x 336x 178x 178x 178x 6x 160x 34x 3x 3x 3x 34x 3x 366x | // Copyright 2026 优谷雅言 open.shengzhiai.com. Licensed under the Apache License, Version 2.0.
// HTTP header helpers without dependencies.
/**
* Parse a Retry-After header value into milliseconds.
* Accepts delta seconds (integer or decimal) and HTTP dates. Returns null when absent or invalid.
*/
export function parseRetryAfter(value, nowMs) {
if (value == null) return null;
const s = String(value).trim();
if (s === '') return null;
if (/^\d+(\.\d+)?$/.test(s)) return Math.round(Number(s) * 1000);
const t = Date.parse(s);
if (Number.isNaN(t)) return null;
const now = typeof nowMs === 'number' ? nowMs : Date.now();
return Math.max(0, t - now);
}
/** Read a header from a Headers-like object or a plain map, case-insensitively. */
export function getHeader(headers, name) {
if (!headers) return null;
if (typeof headers.get === 'function') {
const v = headers.get(name);
return v == null ? null : String(v);
}
const lower = name.toLowerCase();
for (const k of Object.keys(headers)) {
if (k.toLowerCase() === lower) {
const v = headers[k];
return v == null ? null : String(Array.isArray(v) ? v[0] : v);
}
}
return null;
}
|