(signature, url)
| 23 | // antigüedad de una URL entregada al upstream, no un parámetro de rendimiento. |
| 24 | const IMAGE_CACHE_TTL_MS = 10 * 60 * 1000 |
| 25 | // Cuando la URL no dice cuándo muere. Más corto que el tope de arriba a propósito: todo el |
| 26 | // beneficio del caché ocurre dentro de un turno (medido: 6 subidas en 77 s). |
| 27 | const UNKNOWN_EXPIRY_TTL_MS = 4 * 60 * 1000 |
| 28 | // La URL todavía tiene que viajar en el cuerpo y que el upstream vaya a buscarla. Entregar |
| 29 | // una que caduca dentro de dos segundos es entregar una muerta. |
| 30 | const EXPIRY_SAFETY_MARGIN_MS = 30 * 1000 |
| 31 | |
| 32 | /** |
| 33 | * Cuándo muere una URL prefirmada, leído de la propia URL. |
| 34 | * |
| 35 | * `x-oss-date` viene en ISO-8601 básico (`YYYYMMDDTHHMMSSZ`), que Date no parsea, y |
| 36 | * `x-oss-expires` son segundos desde esa fecha. |
| 37 | * |
| 38 | * @param {string} url |
| 39 | * @returns {number|null} epoch ms de la caducidad, o null si la URL no lo dice |
| 40 | */ |
| 41 | const presignedUrlExpiryMs = (url) => { |
| 42 | try { |
| 43 | const params = new URL(String(url)).searchParams |
| 44 | const expires = Number(params.get('x-oss-expires')) |
| 45 | const stamp = params.get('x-oss-date') |
| 46 | if (!Number.isFinite(expires) || expires <= 0 || !stamp) return null |
| 47 | const parts = String(stamp).match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z$/) |
| 48 | if (!parts) return null |
| 49 | const signedAt = Date.UTC(+parts[1], +parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6]) |
| 50 | if (!Number.isFinite(signedAt)) return null |
no test coverage detected